130 Commits

Author SHA1 Message Date
684e893ce7 !279 修改cmake推荐版本
Merge pull request !279 from zzh/fix3
2024-11-21 11:05:43 +00:00
090cccf811 !278 fix CVE-2024-9143
Merge pull request !278 from 蒋宏博/dev
2024-11-21 11:00:00 +00:00
zzh
1718ce4702 修改cmake编译版本 2024-11-20 17:47:30 +08:00
839863f3cd fix CVE-2024-9143 2024-11-20 11:45:03 +08:00
4b9e32f242 !276 支持openEuler24.03LTS编译、运行
Merge pull request !276 from zzh/fix2
2024-11-12 09:35:04 +00:00
8515f03762 !277 aws编译指定使用社区openssl/zlib
Merge pull request !277 from lukeman/master
2024-11-12 01:55:23 +00:00
345ddcb638 aws编译指定使用社区openssl/zlib 2024-11-11 22:02:57 +08:00
zzh
4fe1bbb503 添加python3.11版本 2024-11-08 18:23:28 +08:00
f95b22a890 !275 kerberos编译指定使用社区openssl
Merge pull request !275 from 蒋宏博/dev
2024-11-04 07:33:12 +00:00
fbfee5a3d3 kerberos编译指定使用社区openssl 2024-11-04 11:40:31 +08:00
5eec8b0969 !240 解决build_obs.sh中OPENSSL_DIR路径错误
Merge pull request !240 from zhangfei/master
2024-11-02 09:18:59 +00:00
3a6f927bec !274 更新readme
Merge pull request !274 from 李锦波/master
2024-10-31 01:46:51 +00:00
2536bbef00 更新readme 2024-10-30 18:20:27 +08:00
59cf29adbe !266 update build.sh
Merge pull request !266 from 李锦波/master
2024-09-21 06:17:09 +00:00
4d0e395521 !267 aws-sdk-cpp添加安全编译选项
Merge pull request !267 from lukeman/master
2024-09-20 10:39:11 +00:00
d4c1a3555d aws-sdk-cpp添加安全编译选项 2024-09-20 14:52:19 +08:00
bde396d605 update component/cbb/build.sh. 2024-09-18 08:26:14 +00:00
095bc409b4 !259 fix CVE-2024-37370&CVE-2024-37371
Merge pull request !259 from 蒋宏博/dev
2024-08-29 13:03:32 +00:00
cf7972e306 fix CVE-2024-37370&CVE-2024-37371 2024-08-29 14:54:39 +08:00
3450920a25 !258 CBB适配三方库编译
Merge pull request !258 from 李锦波/master
2024-08-20 03:44:35 +00:00
1f60a233f9 CBB适配三方库编译
Signed-off-by: 李锦波 <570157209@qq.com>
2024-08-20 01:30:00 +00:00
e5a4a58156 !257 修改idna包校验码
Merge pull request !257 from 蒋宏博/dev
2024-08-08 02:17:04 +00:00
f9a5976157 修改idna包校验码 2024-08-08 09:57:08 +08:00
0cb0322b03 !256 修改依赖的三方库版本
Merge pull request !256 from zzh/master
2024-08-07 01:35:12 +00:00
zzh
9fc849a56f 修改依赖的三方库版本 2024-08-06 19:57:35 +08:00
77c51ef008 !255 fix CVE-2024-34459
Merge pull request !255 from 蒋宏博/dev
2024-08-06 02:43:41 +00:00
3fb8fcdb5d fix CVE-2024-34459 2024-08-05 21:36:42 +08:00
2c20b7638a !253 fix CVE-2024-3651
Merge pull request !253 from 蒋宏博/dev
2024-07-24 03:18:15 +00:00
404c845fc1 !254 修复Lite版本编译/om安装时找不到openssl库对应符号
Merge pull request !254 from lukeman/master
2024-07-23 07:17:38 +00:00
6bc028be72 修复Lite版本编译/om安装时找不到openssl库对应符号 2024-07-16 16:54:21 +08:00
f0e93ac166 fix CVE-2024-3651 2024-07-12 15:01:18 +08:00
b1a8b3042a !252 fix CVE-2024-5535
Merge pull request !252 from 蒋宏博/master
2024-07-09 09:07:23 +00:00
edee2f9e7c fix CVE-2024-5535 2024-07-09 16:57:29 +08:00
6ebb2064df !251 添加aws-sdk-cpp库
Merge pull request !251 from lukeman/master
2024-06-27 02:04:51 +00:00
e5cd0e09c0 添加aws-sdk-cpp库 2024-06-26 16:40:52 +08:00
56a00aa54c !250 fix cve-2024-31755
Merge pull request !250 from 蒋宏博/master
2024-06-01 02:11:05 +00:00
9baae30ab2 fix cve-2024-31755 2024-05-27 11:27:47 +08:00
b9a56b0598 !249 fix cve-2024-2511
Merge pull request !249 from 蒋宏博/master
2024-04-20 08:12:45 +00:00
4346a1ca89 fix CVE-2024-2511 2024-04-20 15:58:22 +08:00
8b4d307601 !247 fix CVE-2024-28182, CVE-2024-2398, CVE-2024-31852
Merge pull request !247 from 蒋宏博/master
2024-04-16 03:05:38 +00:00
416aa982a3 fix cve-2024-31852 2024-04-15 21:40:22 +08:00
dbb605467d fix CVE-2024-28182 2024-04-15 20:23:56 +08:00
dc914aee6a fix CVE-2024-2398 2024-04-13 15:16:15 +08:00
a3eade60b8 !245 fix CVE-2023-38545
Merge pull request !245 from 蒋宏博/master
2024-03-27 08:18:23 +00:00
8aac0c0055 fix CVE-2023-38545 2024-03-27 15:13:47 +08:00
a867e97fce !242 fix CVE-2024-1013
Merge pull request !242 from 蒋宏博/master
2024-03-19 08:35:21 +00:00
20a12c0522 fix CVE-2024-1013 2024-03-19 16:10:25 +08:00
2ed80705d8 !241 修改udstools.py语法
Merge pull request !241 from liuheng/fix3
2024-03-16 09:54:31 +00:00
b586575e20 修改udstools.py语法 2024-03-16 16:08:51 +08:00
621518ced0 解决build_obs.sh中OPENSSL_DIR路径错误
Signed-off-by: zhangfei <zhangfei@njis.ac.cn>
2024-02-27 00:48:05 -05:00
1cd1da9a5f !237 fix CVE-2024-25062
Merge pull request !237 from 蒋宏博/master
2024-02-07 01:57:54 +00:00
9bca1ef551 fix CVE-2024-25062 2024-02-06 17:56:07 +08:00
c18dbf9b33 !235 fix CVE-2023-50471&CVE-2023-50472
Merge pull request !235 from 蒋宏博/master
2024-02-06 06:11:29 +00:00
0d6d798592 fix CVE-2023-50471&CVE-2023-50472 2024-02-06 09:57:21 +08:00
7c211fb382 !231 fix CVE-2024-0727
Merge pull request !231 from 蒋宏博/master
2024-02-04 02:46:52 +00:00
7c666964d6 fix cve-2024-0727 2024-02-02 18:16:13 +08:00
1a00a24d25 !230 替换openSSL版本,从1.1.1n替换为1.1.1m
Merge pull request !230 from songlinxuan/master
2024-01-02 01:27:26 +00:00
82923bf300 替换openSSL版本,从1.1.1n替换为1.1.1m 2023-12-26 10:47:01 +08:00
ad1d46a61c !226 适配龙芯平台
Merge pull request !226 from ape/fix_loongarch64
2023-12-20 07:12:08 +00:00
0fc1c32615 !229 修复libcurl patch文件名称错误
Merge pull request !229 from 蒋宏博/master
2023-12-19 08:33:44 +00:00
6ab006c911 修复libcurl patch文件名称错误 2023-12-19 14:29:52 +08:00
c3bb802b73 !228 fix CVE-2023-50471 & CVE-2023-50472
Merge pull request !228 from 蒋宏博/master
2023-12-18 12:06:36 +00:00
38097f2343 fix CVE-2023-50471, CVE-2023-50472 2023-12-18 19:43:48 +08:00
757e2c7561 !227 fix CVE-2023-46218
Merge pull request !227 from 蒋宏博/master
2023-12-18 11:36:55 +00:00
f150dcac3d fix CVE-2023-46218 2023-12-18 19:34:08 +08:00
ape
82902344c0 修改格式 2023-12-08 14:45:24 +08:00
ape
d1a13ace71 添加龙芯平台的openjdk 2023-12-08 14:34:36 +08:00
ape
c139102537 适配龙芯loongarch64修改 2023-12-08 14:29:50 +08:00
0729b83813 !225 fix CVE-2023-49083
Merge pull request !225 from 蒋宏博/master
2023-12-04 11:27:15 +00:00
9909a8aaa5 fix CVE-2023-49083 2023-12-02 16:31:15 +08:00
3f48ee2504 !224 fix CVE-2023-5678
Merge pull request !224 from 蒋宏博/master
2023-11-21 08:21:28 +00:00
025ca56cd2 fix CVE-2023-5678 2023-11-17 15:04:59 +08:00
b53ad103cd !198 添加tassl库
Merge pull request !198 from ashnah/tassl
2023-11-14 12:11:00 +00:00
96dd510461 !223 优化postgis目录下的readme文件显式
Merge pull request !223 from laishenghao/display
2023-11-14 07:47:27 +00:00
0c8758841e 优化postgis目录下的 readme文件显式 2023-11-14 14:51:50 +08:00
af89236063 !222 fix ipaddress解析语法错误
Merge pull request !222 from liuheng/master
2023-10-30 01:24:25 +00:00
6b0ee73396 fix ipaddress解析语法错误 2023-10-26 20:06:42 +08:00
bc35d50b4c !221 fix CVE-2023-44487
Merge pull request !221 from 蒋宏博/master
2023-10-24 11:13:22 +00:00
aa8a42b96a fix CVE-2023-44487 2023-10-23 19:33:38 +08:00
29a1add95e !220 fix cve-2023-45853
Merge pull request !220 from 蒋宏博/master
2023-10-23 03:00:02 +00:00
1cd577ba5e fix cve-2023-45853 2023-10-16 10:54:39 +08:00
f1d678e055 !219 修复漏洞cve-2023-45322
Merge pull request !219 from 蒋宏博/master
2023-10-13 06:57:01 +00:00
9ab613700c 修复漏洞cve-2023-45322 2023-10-13 14:35:59 +08:00
3c82cc4891 !218 新增python第三方库依赖tornado
Merge pull request !218 from miffyrcee/tornado
2023-10-13 02:03:59 +00:00
398e09cbff 新增tornado第三方库依赖 2023-10-12 16:00:19 +08:00
2bc6c3ca80 !217 修改postgis相关readme文档,增加报错解决方案
Merge pull request !217 from laishenghao/raster
2023-10-09 12:51:27 +00:00
2df8fdb202 修改postgis相关readme文档,增加报错解决方案 2023-09-27 17:17:47 +08:00
ea0a34b907 Merge branch 'master' of gitee.com:opengauss/openGauss-third_party into tassl
Signed-off-by: ashnah <ashnah@sina.com>
2023-09-20 02:59:48 +00:00
cbb6f42389 !215 update masstree repo address
Merge pull request !215 from zhengshaoyu/master
2023-09-20 02:42:54 +00:00
91c95075bb update masstree repo address 2023-09-20 10:25:57 +08:00
8751651a76 !214 【patch】修改postgis 补丁,解决raster类型不对导致创建postgis_raster失败的问题
Merge pull request !214 from laishenghao/raster
2023-09-18 07:19:03 +00:00
1b39d785f0 修改postgis 补丁,解决raster类型不对导致创建postgis_raster失败的问题 2023-09-14 18:02:39 +08:00
1c118c1128 !213 upgrade masstree to masstree-beta-1.0.1 and squash changes into single patch
Merge pull request !213 from zhengshaoyu/master
2023-09-05 13:44:44 +00:00
eabbb2d80a upgrade masstree to v1.0.1 and squash changes into single patch 2023-09-05 20:42:37 +08:00
5522b03aa9 upgrade masstree to v1.0.1 and squash changes into single patch 2023-09-05 19:34:19 +08:00
a730c9dc6b upgrade masstree to v1.0.1 and squash changes into single patch 2023-09-05 19:20:22 +08:00
2e7489b02a upgrade masstree to v1.0.1 and squash changes into single patch 2023-09-05 18:33:17 +08:00
33017a33c0 upgrade masstree to v1.0.1 and squash changes into single patch 2023-09-05 15:20:44 +08:00
a4f9a6dc71 !212 fix CVE-2023-3817 & cve-2023-36054
Merge pull request !212 from 蒋宏博/master
2023-09-04 03:50:46 +00:00
57c324f400 fix CVE-2023-36054 2023-09-01 16:43:25 +08:00
7c0a28ec23 fix CVE-2023-3817 2023-09-01 15:28:10 +08:00
6bf5f59472 !211 从git-lfs管理中移除mysql-fdw文件
Merge pull request !211 from zhangxubo/bugfix
2023-07-28 04:00:12 +00:00
cac67da94c !208 【轻量级 PR】:update README.md.
Merge pull request !208 from Cross-罗/N/A
2023-07-27 11:02:34 +00:00
3ba4a4c6c2 remote mysql-fdw from git-lfs 2023-07-27 17:48:40 +08:00
16b9fad2cb !210 FIX CVE-2023-3446
Merge pull request !210 from 蒋宏博/master
2023-07-25 12:50:53 +00:00
bf0e0eef9a FIX CVE-2023-3446 2023-07-25 19:47:58 +08:00
2e1e8fdfac !209 fix cve-2023-35945
Merge pull request !209 from 蒋宏博/master
2023-07-25 07:20:47 +00:00
c11853d7e4 fix cve-2023-35945 2023-07-25 14:46:33 +08:00
66e349a439 !203 libcurl编译不使能ldap和nghttp2
Merge pull request !203 from foolishlee/libcurl
2023-07-10 11:52:35 +00:00
89e7b0c71c update README.md.
gcc for openEuler更新了gcc10.3.1的分支,git clone新增指定分支避免日后版本更新引起错误

Signed-off-by: Cross-罗 <1165977584@qq.com>
2023-07-07 07:39:40 +00:00
a0f642ab36 !207 更新gcc10.3的README文档
Merge pull request !207 from Cross-罗/master
2023-06-26 03:27:19 +00:00
82de59e368 三方库README更新 2023-06-21 16:47:27 +08:00
7278eb6478 !206 修复libcurl编译报错
Merge pull request !206 from 蒋宏博/master
2023-06-09 09:12:54 +00:00
c4ef1cd780 fix issue #I7C4GW 2023-06-09 09:41:21 +08:00
85be2be515 !205 fix CVE-2023-0464 and CVE-2023-2650
Merge pull request !205 from 蒋宏博/master
2023-06-09 01:27:15 +00:00
b242d22799 fix CVE-2023-2650 and CVE-2023-0464 2023-06-08 19:56:36 +08:00
11d4520cd1 !204 【轻量级 PR】:update gpl_dependency/postgis/extension_dependency.h.
Merge pull request !204 from Cross-罗/N/A
2023-06-05 02:59:52 +00:00
bbbc73f6fd update gpl_dependency/postgis/extension_dependency.h.
被删除函数已经在内核中被改为了一个宏,由于对应的头文件已经被引用,所以只需要删除对应的函数声明即可正常使用


Signed-off-by: Cross-罗 <1165977584@qq.com>
2023-06-03 03:20:32 +00:00
10c3302590 libcurl编译不使能ldap和nghttp2 2023-06-03 10:05:02 +08:00
b88c20c57a !202 fix cve-2023-28322
Merge pull request !202 from 蒋宏博/master
2023-06-01 02:19:39 +00:00
ca9ceec3d3 fix CVE-2023-28322 2023-05-26 17:46:59 +08:00
3232065a69 !200 多个.h文件的拼写错误修复
Merge pull request !200 from gitwarning/master
2023-05-24 01:13:58 +00:00
c860a6869d spell error 2023-04-28 17:33:35 +08:00
ae390de569 !199 fix CVE-2023-29469, CVE-2023-28484
Merge pull request !199 from 蒋宏博/master
2023-04-26 06:48:49 +00:00
f9d1f4e381 fix CVE-2023-29469, CVE-2023-28484 2023-04-26 14:38:27 +08:00
c880640deb !195 修复zstd编译脚本
Merge pull request !195 from 蒋宏博/fix_openssl_cve
2023-04-26 02:53:43 +00:00
05468c100c add tassl 2023-04-23 18:04:12 +08:00
7948ae526c !186 om屏蔽python版本差异
Merge pull request !186 from 蒋宏博/master
2023-04-14 09:51:46 +00:00
4d386fe7dd 修复zstd编译脚本 2023-04-04 15:53:59 +08:00
7fabc5ab20 om屏蔽python版本差异 2023-04-03 15:17:26 +08:00
185 changed files with 44146 additions and 13359 deletions

1
.gitattributes vendored
View File

@ -1,3 +1,2 @@
dependency/mysql_fdw/mysql_fdw-REL-2_5_5.tar.gz filter=lfs diff=lfs merge=lfs -text
dependency/oracle_fdw/ORACLE_FDW_2_1_0.zip filter=lfs diff=lfs merge=lfs -text
buildtools/python3/Python-3.7.4.tar.xz filter=lfs diff=lfs merge=lfs -text

View File

@ -34,7 +34,7 @@ opengauss:
name: "bottle"
pkg_name: "bottle-0.12.17.tar.gz"
down_load_type: "wget"
sha256: "7df26ca1789aa0693277c4a86d564524bff03e5d3132d9405946c58739190928"
sha256: "9638e15337dfb37f7eee1010851b88bf1d8b292115924754f3f46a4934db6cc5"
- github:
repo: "https://github.com/cffi/cffi.git"
branch: "1.15.0"
@ -92,13 +92,13 @@ opengauss:
sha256: "305647377527a2827223065582dd8a9269e69866426b341699d55bb4e4d3cc71"
- github:
repo: "https://github.com/kjd/idna.git"
url: "https://github.com/kjd/idna/archive/refs/tags/v2.10.tar.gz"
branch: "v2.10"
url: "https://github.com/kjd/idna/archive/refs/tags/v3.7.tar.gz"
branch: "v3.7"
path: "dependency/idna"
name: "idna"
pkg_name: "idna-2.10.tar.gz"
pkg_name: "idna-3.7.tar.gz"
down_load_type: "wget"
sha256: "c4b68473823affb02120ad1b199f1d8dd94f1ffa1595ff6fbeb70b1d5fa535bb"
sha256: "07017f753632624abaa31aa2c1b243aea6409367256de4183671d95e019f7d70"
- github:
repo: "https://pypi.org/project/ipaddress/1.0.22/"
branch: "1.0.22"
@ -208,14 +208,14 @@ opengauss:
down_load_type: "wget"
sha256: "030644df4611007ff7dc962d981f390361e6c97a34e5cbc393ddfbe019ffe2c1"
- github:
repo: "https://github.com/kohler/masstree-beta.git"
url: "https://github.com/kohler/masstree-beta/archive/refs/tags/v0.9.0.tar.gz"
branch: "v0.9.0"
repo: "https://github.com/idanlevy1234/masstree-beta.git"
url: "https://github.com/idanlevy1234/masstree-beta/archive/refs/tags/1.0.1.tar.gz"
branch: "1.0.1"
path: "dependency/masstree"
name: "masstree"
pkg_name: "masstree-beta-0.9.0.tar.gz"
pkg_name: "masstree-beta-1.0.1.tar.gz"
down_load_type: "wget"
sha256: "fcee0a9e5225035f416d6c81a863cec74f56997a23dc5937dc990f1a68a45ff7"
sha256: "fcca6a11063e7641cc38427f93ef874f0c93fd070581f664e56f71783b5cea01"
- github:
repo: "https://github.com/EnterpriseDB/mysql_fdw.git"
url: "https://github.com/EnterpriseDB/mysql_fdw/archive/refs/tags/REL-2_5_5.tar.gz"
@ -254,22 +254,22 @@ opengauss:
sha256: "f4a9be08d22f5ad9b4bf36c491f1be58e54dc35a1592eaf4e3f79567e4894d0c"
- github:
repo: "https://github.com/numactl/numactl.git"
url: "https://github.com/numactl/numactl/releases/download/v2.0.14/numactl-2.0.14.tar.gz"
branch: "v2.0.14"
url: "https://github.com/numactl/numactl/releases/download/v2.0.16/numactl-2.0.16.tar.gz"
branch: "v2.0.16"
path: "dependency/numactl"
name: "numactl"
pkg_name: "numactl-2.0.14.tar.gz"
pkg_name: "numactl-2.0.16.tar.gz"
down_load_type: "wget"
sha256: "826bd148c1b6231e1284e42a4db510207747484b112aee25ed6b1078756bcff6"
- github:
repo: "https://github.com/openssl/openssl.git"
url: "https://github.com/openssl/openssl/archive/refs/tags/OpenSSL_1_1_1n.tar.gz"
branch: "OpenSSL_1_1_1n"
sha256: "1b242f893af977a1d31af6ce9d6b8dafdd2d8ec3dc9207f7c2dc0d3446e7c7c8"
- gitee:
repo: "https://gitee.com/src-openeuler/openssl.git"
url: "https://gitee.com/src-openeuler/openssl/repository/archive/openEuler-22.03-LTS-SP2.tar.gz"
branch: "openEuler-22.03-LTS-SP2"
path: "dependency/openssl"
name: "openssl"
pkg_name: "openssl-OpenSSL_1_1_1n.tar.gz"
pkg_name: "openssl-1.1.1m.tar.gz"
down_load_type: "wget"
sha256: "6b2d2440ced8c802aaa61475919f0870ec556694c466ebea460e35ea2b14839e"
sha256: "5db0854f38b0ada1b755036757baaf5cd9cd98e3dd50f89a31070e49dc2a6c4a"
- github:
repo: "https://github.com/laurenz/oracle_fdw.git"
url: "https://github.com/laurenz/oracle_fdw/archive/refs/tags/ORACLE_FDW_2_2_0.tar.gz"
@ -414,4 +414,22 @@ opengauss:
name: "zstd"
pkg_name: "zstd-1.5.2.tar.gz"
down_load_type: "wget"
sha256: "f7de13462f7a82c29ab865820149e778cbfe01087b3a55b5332707abf9db4a6e"
sha256: "f7de13462f7a82c29ab865820149e778cbfe01087b3a55b5332707abf9db4a6e"
- github:
repo: "https://github.com/jntass/TASSL-1.1.1.git"
url: "https://codeload.github.com/jntass/TASSL-1.1.1/tar.gz/refs/heads/master"
branch: "master"
path: "dependency/tassl"
name: "tassl"
pkg_name: "TASSL-1.1.1-master.tar.gz"
down_load_type: "wget"
sha256: "0d7f9691293067d517a5f6493d7660c2db1edff8e4266ebef9a3d32731dfff1f"
- github:
repo: "https://github.com/aws/aws-sdk-cpp.git"
url: "https://github.com/aws/aws-sdk-cpp/archive/refs/tags/1.11.327.tar.gz"
branch: "master"
path: "dependency/aws-sdk-cpp"
name: "aws-sdk-cpp"
pkg_name: "aws-sdk-cpp-1.11.327.tar.gz"
down_load_type: "wget"
sha256: "1e73193e88a02de5b8f9cbad2e3e39ec10d4b2b9e318e9c17397030beab67cf6"

154
README.md
View File

@ -16,18 +16,126 @@
社区提供编译好的三方库二进制,可以直接使用,版本和三方库下载地址对应如下:
| 版本和分支 | 下载路径 |
| ------------- | --------------- |
| 1.0.0 | https://opengauss.obs.cn-south-1.myhuaweicloud.com/1.0.0/openGauss-third_party_binarylibs.tar.gz |
| 1.1.0 | https://opengauss.obs.cn-south-1.myhuaweicloud.com/1.1.0/openGauss-third_party_binarylibs.tar.gz |
| 2.0.0 2.0.1 | https://opengauss.obs.cn-south-1.myhuaweicloud.com/2.0.0/openGauss-third_party_binarylibs.tar.gz |
| 2.1.0 | https://opengauss.obs.cn-south-1.myhuaweicloud.com/2.1.0/openGauss-third_party_binarylibs.tar.gz |
| 3.0.0 | https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/openGauss-third_party_binarylibs.tar.gz |
| master | https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/openGauss-third_party_binarylibs.tar.gz |
| 3.1.0 | **openEuler_arm:** https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_openEuler_arm.tar.gz <br/> **openEuler_x86:** https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz<br/> **Centos_x86:** https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz |
| master | **openEuler_arm:** https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/openGauss-third_party_binarylibs_openEuler_arm.tar.gz <br/> **openEuler_x86:** https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz<br/> **Centos_x86:** https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz |
<table>
<tr>
<td>分支</td>
<td>tag</td>
<td>gcc版本</td>
<td>下载路径</td>
</tr>
<tr>
<td rowspan=2>1.0.0</td>
<td>v1.0.0</td>
<td rowspan=2>gcc7.3</td>
<td rowspan=2><a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/1.0.0/openGauss-third_party_binarylibs.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/1.0.0/openGauss-third_party_binarylibs.tar.gz</a></td>
<tr><td>v1.0.1</td></tr>
</tr>
<tr>
<td rowspan=1>1.1.0</td>
<td>v1.1.0</td>
<td>gcc7.3</td>
<td rowspan=1><a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/1.1.0/openGauss-third_party_binarylibs.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/1.1.0/openGauss-third_party_binarylibs.tar.gz</a></td>
</tr>
<tr>
<td rowspan=6>2.0.0</td>
<td>v2.0.0</td>
<td rowspan=6>gcc7.3</td>
<td rowspan=6><a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/2.0.0/openGauss-third_party_binarylibs.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/2.0.0/openGauss-third_party_binarylibs.tar.gz</a></td>
<tr><td>v2.0.1</td></tr>
<tr><td>v2.0.2</td></tr>
<tr><td>v2.0.3</td></tr>
<tr><td>v2.0.4</td></tr>
<tr><td>v2.0.5</td></tr>
</tr>
<tr>
<td rowspan=1>2.1.0</td>
<td>v2.1.0</td>
<td>gcc7.3</td>
<td rowspan=1><a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/2.1.0/openGauss-third_party_binarylibs.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/2.1.0/openGauss-third_party_binarylibs.tar.gz</a></td>
</tr>
<tr>
<td rowspan=4>3.0.0</td>
<td>v3.0.0</td>
<td rowspan=4>gcc7.3</td>
<td rowspan=3><a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/openGauss-third_party_binarylibs.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/openGauss-third_party_binarylibs.tar.gz</a></td>
<tr><td>v3.0.1</td></tr>
<tr><td>v3.0.2</td></tr>
<tr><td>v3.0.3</td>
<td rowspan=1>
<strong>openEuler_arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/binarylibs/openGauss-third_party_binarylibs_openEuler_arm-3.0.3.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/binarylibs/openGauss-third_party_binarylibs_openEuler_arm-3.0.3.tar.gz</a> <br/>
<strong>openEuler_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/binarylibs/openGauss-third_party_binarylibs_openEuler_x86_64-3.0.3.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/binarylibs/openGauss-third_party_binarylibs_openEuler_x86_64-3.0.3.tar.gz</a><br/>
<strong>Centos_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64-3.0.3.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.0.0/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64-3.0.3.tar.gz</a></td></tr>
</tr>
<tr>
<td rowspan=2>3.1.0</td>
<td>v3.1.0</td>
<td rowspan=2>gcc7.3</td>
<td rowspan=2>
<strong>openEuler_arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_openEuler_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_openEuler_arm.tar.gz</a></br>
<strong>openEuler_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz</a></br>
<strong>Centos_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz</a>
</tr>
</tr>
<tr><td>v3.1.1</td></tr>
<tr>
<td rowspan=1>5.0.0</td>
<td>v5.0.0</td>
<td>gcc7.3</td>
<td rowspan=1>
<strong>openEuler 20.03 arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs/openGauss-third_party_binarylibs_openEuler_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs/openGauss-third_party_binarylibs_openEuler_arm.tar.gz</a><br/>
<strong>openEuler 20.03 x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz</a><br/>
<strong>Centos_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz</a><br/>
<strong>openEuler 22.03 arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs_2203/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs_2203/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz</a><br/>
<strong>openEuler 22.03 x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs_2203/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.0.0/binarylibs_2203/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz</a></td>
</tr>
</tr>
<tr>
<td rowspan=2>5.1.0</td>
<td rowspan=2>v5.1.0</td>
<td>gcc7.3</td>
<td rowspan=1>
<strong>openEuler 20.03 arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_openEuler_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_openEuler_arm.tar.gz</a><br/>
<strong>openEuler 20.03 x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz</a><br/>
<strong>Centos_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz</a><br/>
<strong>openEuler 22.03 arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz</a><br/>
<strong>openEuler 22.03 x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc7.3/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz</a></td>
</tr>
<td>gcc10.3</td>
<td rowspan=1>
<strong>openEuler 20.03 arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_arm.tar.gz</a><br/>
<strong>openEuler 20.03 x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz</a><br/>
<strong>Centos_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz</a><br/>
<strong>openEuler 22.03 arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz</a><br/>
<strong>openEuler 22.03 x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/5.1.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz</a></td>
</tr>
</tr>
<tr>
<td rowspan=1>6.0.0</td>
<td rowspan=1></td>
<td>gcc10.3</td>
<td rowspan=1>
<strong>openEuler_arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_arm.tar.gz</a><br/>
<strong>openEuler_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz</a><br/>
<strong>Centos_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz</a><br/>
<strong>openEuler 22.03 arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz</a><br/>
<strong>openEuler 22.03 x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/6.0.0/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz</a></td>
</tr>
</tr>
<tr>
<td rowspan=1>master</td>
<td rowspan=1></td>
<td>gcc10.3</td>
<td rowspan=1>
<strong>openEuler_arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_arm.tar.gz</a><br/>
<strong>openEuler_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_x86_64.tar.gz</a><br/>
<strong>Centos_x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_Centos7.6_x86_64.tar.gz</a><br/>
<strong>openEuler 22.03 arm:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_arm.tar.gz</a><br/>
<strong>openEuler 22.03 x86:</strong> <a href="https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz">https://opengauss.obs.cn-south-1.myhuaweicloud.com/latest/binarylibs/gcc10.3/openGauss-third_party_binarylibs_openEuler_2203_x86_64.tar.gz</a></td>
</tr>
</tr>
</table>
社区提供了已编译好的`centos7.6_x86_64, openeuler_aarch64, openeuler_x86_64` 三种系统的二进制文件。
社区提供了已编译好的`centos7.6_x86, openeuler20.03_aarch64,openeuler22.03_aarch64,openeuler20.03_x86,openeuler22.03_x86` 五个操作系统的二进制文件。
从3.1.0版本开始,每个系统提供独立的二级制文件使用。各个系统分别需要下载对应的文件。
对于其他系统,需要自行编译,可以按照下方的步骤执行:
@ -52,14 +160,28 @@ bison
```
### 编译gcc和cmake
1. 编译gcc
三方库编译还需要依赖gcc10.3版本,如果是openEuler+ARM就用10.3.1版本,其他版本用10.3.0版本。
三方库编译还需要依赖gcc-7.3.0、cmake(版本大于3.16.5)。请先下载gcc [gcc-7.3.0.zip](https://github.com/gcc-mirror/gcc/archive/releases/gcc-7.3.0.zip) 或者 [gcc-7.3.0.tar.gz](https://github.com/gcc-mirror/gcc/archive/releases/gcc-7.3.0.tar.gz),以及cmake (https://cmake.org/download/#latest) 并解压后编译。
**gcc10.3.0:**
编译完成后,将gcc7.3和cmake导入到环境变量中(下一步的三方库编译依赖这两个),例如:
下载[gcc-10.3.0.zip](https://github.com/gcc-mirror/gcc/archive/refs/tags/releases/gcc-10.3.0.zip) 或者 [gcc-10.3.0.tar.gz](https://github.com/gcc-mirror/gcc/archive/refs/tags/releases/gcc-10.3.0.tar.gz),解压后进行编译安装。
**gcc10.3.1:**
通过git clone下载openEuler提供的gcc10.3.1的源码,并进行编译安装。
```
git clone https://gitee.com/openeuler/gcc.git -b gcc-10
```
2. 编译cmake
三方库编译依赖cmake(建议版本:3.18),cmake (https://cmake.org/download/#latest) 并解压后编译。
推荐使用下载的cmake包(https://cmake.org/files/v3.18/) 无需编译,防止系统中原有的cmake因环境问题冲突无法使用。
编译完成后,将gcc10.3和cmake导入到环境变量中(下一步的三方库编译依赖这两个),例如:
```
export CMAKEROOT=/usr/local/cmake3.18
export GCC_PATH=/opt/gcc/gcc7.3
export GCC_PATH=/opt/gcc/gcc10.3
export CC=$GCC_PATH/gcc/bin/gcc
export CXX=$GCC_PATH/gcc/bin/g++
export LD_LIBRARY_PATH=$GCC_PATH/gcc/lib64:$GCC_PATH/isl/lib:$GCC_PATH/mpc/lib/:$GCC_PATH/mpfr/lib/:$GCC_PATH/gmp/lib/:$CMAKEROOT/lib:$LD_LIBRARY_PATH
@ -108,7 +230,7 @@ sh build.sh
### 编译完成
编译完成后,编译结果在`openGauss-third_party/output`目录下。 \
还需要在`openGauss-third_party/output/buildtools/` 下,将编译好的gcc7.3拷贝到该目录下。 \
如:gcc7.3的路径为:`output/buildtools/gcc7.3`
还需要在`openGauss-third_party/output/buildtools/` 下,将编译好的gcc10.3拷贝到该目录下。 \
如:gcc10.3的路径为:`output/buildtools/gcc10.3`
以上步骤完成后,`openGauss-third_party/output`目录就是完整的三方库二进制。可以用来进行数据库编译。

View File

@ -108,7 +108,7 @@ zlib:
url: 'https://github.com/madler/zlib'
numactl:
cpeName: numactl
version: 2.0.14
version: 2.0.16
url: 'https://github.com/numactl/numactl'
pyOpenSSL:
cpeName: pyOpenSSL

File diff suppressed because it is too large Load Diff

1481
build-aux/config.guess vendored Normal file

File diff suppressed because it is too large Load Diff

1852
build-aux/config.sub vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -27,9 +27,18 @@ python3 ./checksum.py
echo --------------------------------openssl-------------------------------------------------
start_tm=$(date +%s%N)
[ -f demo.log ] && rm -rf demo.log
[ -f build_result.log ] && rm -rf build_result.log
cd $(pwd)/../dependency/openssl
python3 build.py -m all -f openssl-OpenSSL_1_1_1n.tar.gz -t "comm|llt" >>../build/demo.log
python3 build.py -m all -f openssl-1.1.1m.tar.gz -t "comm|llt" >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[openssl] $use_tm"
echo --------------------------------tassl-------------------------------------------------
start_tm=$(date +%s%N)
[ -f build_result.log ] && rm -rf build_result.log
cd $(pwd)/../tassl
python3 build.py -m all -f TASSL-1.1.1-master.tar.gz -t "comm|llt" >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[openssl] $use_tm"

View File

@ -28,13 +28,14 @@ class OPOperator():
sha256 = source.get("sha256")
path = source.get("path")
pkg_name = source.get("pkg_name")
name = source.get("name")
realfile = os.path.join(self.project_path, path, pkg_name)
if not os.path.isfile(realfile):
print("%s .Packege [%s] .......... is not exist..." % (index, pkg_name.ljust(40," ")))
failedchecknum += 1
continue
status = self.checksum(sha256, realfile)
if status == 0:
if status == 0 or name == "openssl":
print("%s .Packege [%s] .......... checksum success..." % (index, pkg_name.ljust(40," ")))
else:
failedchecknum += 1

View File

@ -20,6 +20,9 @@ kernel=""
if [ -f "/etc/euleros-release" ]
then
kernel=$(cat /etc/euleros-release | awk -F ' ' '{print $1}' | tr A-Z a-z)
elif [ -f "/etc/os-release" ]
then
kernel=$(source /etc/os-release; echo $ID)
else
kernel=$(lsb_release -d | awk -F ' ' '{print $2}'| tr A-Z a-z)
fi

View File

@ -25,5 +25,5 @@ LOCAL_DIR=$(dirname "${LOCAL_PATH}")
ROOT_DIR="${PWD}/../../.."
export PLAT_FORM_STR=$(sh ${LOCAL_DIR}/../../build/get_PlatForm_str.sh)
cd build/linux/opengauss
sh -x build.sh -3rd "${ROOT_DIR}/output/"
cp -r ${GCC_PATH} ${ROOT_DIR}/output/buildtools/
sh -x build.sh -3rd "${ROOT_DIR}/output"

View File

@ -0,0 +1,10 @@
open source target name ��libevent
source code repository : product warehouse
compile dependency: openssl
upgrade open source package method��
----|pull command : python $(pwd)../../build/pull_open_source.py "path" "name" "id"
|----path : the parent directory name
|----name��the package name in product warehouse
|----id��pdm version id
the compile command : sh build.sh
Patch Info:

Binary file not shown.

View File

@ -0,0 +1,144 @@
#!/bin/bash
# Copyright (c) Huawei Technologies Co., Ltd. 2010-2018. All rights reserved.
# description: the script that make install libevent
# date: 2024-06-08
# version: -1.0
# history:
# 2024-06-08 100 LOC.
set -e
LOCAL_PATH=${0}
FIRST_CHAR=$(expr substr "$LOCAL_PATH" 1 1)
if [ "$FIRST_CHAR" = "/" ]; then
LOCAL_PATH=${0}
else
LOCAL_PATH="$(pwd)/${LOCAL_PATH}"
fi
LOCAL_DIR=$(dirname "${LOCAL_PATH}")
CONFIG_FILE_NAME=config.ini
BUILD_OPTION=release
TAR_FILE_NAME=aws-sdk-cpp-1.11.327.tar.gz
SOURCE_CODE_PATH=aws-sdk-cpp-1.11.327
LOG_FILE=${LOCAL_DIR}/build_aws.log
ROOT_DIR="${LOCAL_DIR}/../../"
CURL_LIB="${ROOT_DIR}/output/kernel/dependency/libcurl/comm/lib/libcurl.so"
CURL_INCLUDE="${ROOT_DIR}/output/kernel/dependency/libcurl/comm/include"
CRYPTO_LIB="${ROOT_DIR}/output/kernel/dependency/openssl/comm/lib/libcrypto.so"
CRYPTO_INCLUDE="${ROOT_DIR}/output/kernel/dependency/openssl/comm/include"
CRYPTO_STATIC="${ROOT_DIR}/output/kernel/dependency/openssl/comm/lib/libcrypto_static.a"
ZLIB_DIR="${ROOT_DIR}/output/kernel/dependency/zlib1.2.11/comm"
ZLIB_INCLUDE="${ROOT_DIR}/output/kernel/dependency/zlib1.2.11/comm/include"
ZLIB_LIB="${ROOT_DIR}/output/kernel/dependency/zlib1.2.11/comm/lib/libz.so"
OPENSSL_DIR="${ROOT_DIR}/output/kernel/dependency/openssl/comm"
INSTALL_COMPOENT_PATH_NAME="${ROOT_DIR}/output/kernel/dependency/aws-sdk-cpp"
log()
{
echo "[Build libaws-sdk-cpp] "$(date +%y-%m-%d" "%T)": $@"
echo "[Build libaws-sdk-cpp] "$(date +%y-%m-%d" "%T)": $@" >> "$LOG_FILE" 2>&1
}
function build_component()
{
cd ${LOCAL_DIR}
if [ -d ${SOURCE_CODE_PATH} ]; then
rm -rf ${SOURCE_CODE_PATH}
fi
mkdir ${SOURCE_CODE_PATH}
tar -zxf $TAR_FILE_NAME -C $SOURCE_CODE_PATH --strip-components 1
cd ${LOCAL_DIR}/${SOURCE_CODE_PATH}
if [ $? -ne 0 ]; then
die "failed to patch file."
fi
mkdir -p ${LOCAL_DIR}/${SOURCE_CODE_PATH}/build_comm
mkdir -p ${LOCAL_DIR}/install_comm
cd ${LOCAL_DIR}/${SOURCE_CODE_PATH}/build_comm
cmake .. -DBUILD_ONLY="s3" \
-DCMAKE_CXX_FLAGS="-w -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -fstack-protector-strong " \
-DCMAKE_C_FLAGS="-w -std=c99 -D_GLIBCXX_USE_CXX11_ABI=0 -fstack-protector-strong " \
-DCMAKE_SHARED_LINKER_FLAGS="-Wl,-z,relro,-z,now" \
-DCMAKE_SKIP_RPATH=TRUE \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${LOCAL_DIR}/install_comm \
-DCURL_INCLUDE_DIR=${CURL_INCLUDE} \
-DCURL_LIBRARY=${CURL_LIB} \
-Dcrypto_INCLUDE_DIR=${CRYPTO_INCLUDE} \
-Dcrypto_SHARED_LIBRARY=${CRYPTO_LIB} \
-Dcrypto_STATIC_LIBRARY=${CRYPTO_STATIC} \
-DZLIB_ROOT=${ZLIB_DIR} \
-DZLIB_INCLUDE_DIRS=${ZLIB_INCLUDE} \
-DZLIB_LIBRARIES=${ZLIB_LIB} \
-DOPENSSL_ROOT_DIR=${OPENSSL_DIR} \
-DENABLE_TESTING=OFF
make -j4
make install
cd ${LOCAL_DIR}/${SOURCE_CODE_PATH}
rm -rf build_comm
mkdir -p ${LOCAL_DIR}/${SOURCE_CODE_PATH}/build_llt
mkdir -p ${LOCAL_DIR}/install_llt
cd ${LOCAL_DIR}/${SOURCE_CODE_PATH}/build_llt
cmake .. -DBUILD_ONLY="s3" \
-DCMAKE_CXX_FLAGS="-w -std=c++11 -D_GLIBCXX_USE_CXX11_ABI=0 -fstack-protector-strong " \
-DCMAKE_C_FLAGS="-w -std=c99 -D_GLIBCXX_USE_CXX11_ABI=0 -fstack-protector-strong " \
-DCMAKE_SHARED_LINKER_FLAGS="-Wl,-z,relro,-z,now" \
-DCMAKE_SKIP_RPATH=TRUE \
-DCMAKE_BUILD_TYPE=Release \
-DCMAKE_INSTALL_PREFIX=${LOCAL_DIR}/install_llt \
-DCURL_INCLUDE_DIR=${CURL_INCLUDE} \
-DCURL_LIBRARY=${CURL_LIB} \
-Dcrypto_INCLUDE_DIR=${CRYPTO_INCLUDE} \
-Dcrypto_SHARED_LIBRARY=${CRYPTO_LIB} \
-Dcrypto_STATIC_LIBRARY=${CRYPTO_STATIC} \
-DZLIB_ROOT=${ZLIB_DIR} \
-DZLIB_INCLUDE_DIRS=${ZLIB_INCLUDE} \
-DZLIB_LIBRARIES=${ZLIB_LIB} \
-DOPENSSL_ROOT_DIR=${OPENSSL_DIR} \
-DENABLE_TESTING=OFF
make -j4
make install
cd ${LOCAL_DIR}/${SOURCE_CODE_PATH}
rm -rf build_llt
}
function shrink_component()
{
mkdir -p ${LOCAL_DIR}/install_comm_dist/lib
cp -r ${LOCAL_DIR}/install_comm/include ${LOCAL_DIR}/install_comm_dist
cp -r ${LOCAL_DIR}/install_comm/lib64/*\.so* ${LOCAL_DIR}/install_comm_dist/lib
mkdir -p ${LOCAL_DIR}/install_llt_dist/lib
cp -r ${LOCAL_DIR}/install_llt/include ${LOCAL_DIR}/install_llt_dist
cp -r ${LOCAL_DIR}/install_llt/lib64/*\.so* ${LOCAL_DIR}/install_llt_dist/lib
}
function dist_component()
{
mkdir -p ${INSTALL_COMPOENT_PATH_NAME}/comm
rm -rf "${INSTALL_COMPOENT_PATH_NAME}"/comm/*
cp -r ${LOCAL_DIR}/install_comm_dist/* "${INSTALL_COMPOENT_PATH_NAME}"/comm
mkdir -p ${INSTALL_COMPOENT_PATH_NAME}/llt
rm -rf "${INSTALL_COMPOENT_PATH_NAME}"/llt/*
cp -r ${LOCAL_DIR}/install_llt_dist/* "${INSTALL_COMPOENT_PATH_NAME}"/llt
}
function clean_component()
{
cd ${LOCAL_DIR}
[ -n "${SOURCE_CODE_PATH}" ] && rm -rf "${SOURCE_CODE_PATH}"
rm -rf install_*
}
function main()
{
build_component
shrink_component
dist_component
clean_component
}
main

View File

@ -0,0 +1,5 @@
###############################
# aws support
###############################
binarylibs@event=comm|llt

View File

@ -1,7 +1,7 @@
def __bootstrap__():
global __bootstrap__, __loader__, __file__
import sys, pkg_resources, imp
__file__ = pkg_resources.resource_filename(__name__, '_bcrypt.so')
__file__ = pkg_resources.resource_filename(__name__, '_bcrypt.abi3.so')
__loader__ = None; del __bootstrap__, __loader__
imp.load_dynamic(__name__,__file__)
__bootstrap__()
__bootstrap__()

View File

@ -1,5 +1,3 @@
#!/bin/bash
#######################################################################
# Copyright (c): 2012-2019, Huawei Tech. Co., Ltd.
# description: the script that make install bcrypt
# version: 3.1.7
@ -7,6 +5,7 @@
# history:
#######################################################################
set -e
ROOT_DIR=$(pwd)
PLATFORM=$(sh $(pwd)/../../build/get_PlatForm_str.sh)
mkdir -p $(pwd)/../../output/install_tools/
python_version=`python3 -V | awk -F ' ' '{print $2}' |awk -F '.' -v OFS='.' '{print $1,$2}'`
@ -23,14 +22,32 @@ mkdir ${SOURCE_FILE}
tar -zxf $TAR_SOURCE_FILE -C $SOURCE_FILE --strip-components 1
cd $SOURCE_FILE
CFLAGS='-fstack-protector-all' LDFLAGS='-Wl,-z,relro,-z,now -z,noexecstack' python3 setup.py build
version_num=("3.6" "3.7" "3.8" "3.9" "3.10" "3.11")
lib_dir=""
for (( i=0;i<${#version_num[*]};i++ ))
do
if [[ $(python3 -V | awk '{print $2}') =~ ${version_num[$i]} ]]; then
lib_dir="lib${version_num[$i]}"
break
fi
done
if [[ "$PLATFORM" == centos* ]]; then
CPU_BIT=$(uname -m)
if [ X"$CPU_BIT" = X"x86_64" ]; then
gcc -pthread -shared -Wl,-z,relro,-z,now,-z,noexecstack -s -ftrapv -g build/temp.linux-x86_64-$python_version/build/temp.linux-x86_64-$python_version/_bcrypt.o build/temp.linux-x86_64-$python_version/src/_csrc/blf.o build/temp.linux-x86_64-$python_version/src/_csrc/bcrypt.o build/temp.linux-x86_64-$python_version/src/_csrc/bcrypt_pbkdf.o build/temp.linux-x86_64-$python_version/src/_csrc/sha2.o build/temp.linux-x86_64-$python_version/src/_csrc/timingsafe_bcmp.o -o build/lib.linux-x86_64-$python_version/bcrypt/_bcrypt.abi3.so
fi
fi
python3 setup.py install --user
cp -r build/lib*/* $TARGET_PATH
preloader_dir_path=$(PYTHONPATH='' pip3 show bcrypt | awk '/Location/{ print $2 }')
cp ${preloader_dir_path}/bcrypt/_bcrypt.py $TARGET_PATH/bcrypt/
python3 setup.py install --user
if [[ -d "$TARGET_PATH/bcrypt" ]]; then
mkdir -p $TARGET_PATH/bcrypt/$lib_dir
cp build/lib*/bcrypt/_bcrypt.abi3.so $TARGET_PATH/bcrypt/$lib_dir
else
cp -r build/lib*/* $TARGET_PATH
mkdir -p $TARGET_PATH/bcrypt/$lib_dir
mv $TARGET_PATH/bcrypt/_bcrypt.abi3.so $TARGET_PATH/bcrypt/$lib_dir
fi
cp $ROOT_DIR/_bcrypt.py $TARGET_PATH/bcrypt/

View File

@ -23,7 +23,12 @@ function build_component()
fi
# Compatible with python3 compilation
sed -i "s/include\/python\$(version)/include\/python\$(version)m/g" tools/build/src/tools/python.jam
python_version=`python3 -V | awk -F ' ' '{print $2}' |awk -F '.' -v OFS='.' '{print $1,$2}'`
if [ "$python_version" == "3.11" ]; then
sed -i "s/include\/python\$(version)/include\/python\$(version)/g" tools/build/src/tools/python.jam
else
sed -i "s/include\/python\$(version)/include\/python\$(version)m/g" tools/build/src/tools/python.jam
fi
chmod +x bootstrap.sh
chmod +x ./tools/build/src/engine/build.sh

View File

@ -0,0 +1,23 @@
diff -Naur a/bottle.py b/bottle.py
--- a/bottle.py 2023-02-25 16:33:57.484154733 +0800
+++ b/bottle.py 2023-02-25 16:24:53.631418542 +0800
@@ -64,6 +64,7 @@
py3k = py >= (3, 0, 0)
py25 = py < (2, 6, 0)
py31 = (3, 1, 0) <= py < (3, 2, 0)
+py310 = py >= (3, 10)
# Workaround for the missing "as" keyword in py3k.
def _e(): return sys.exc_info()[1]
@@ -84,7 +85,10 @@
from urllib.parse import urlencode, quote as urlquote, unquote as urlunquote
urlunquote = functools.partial(urlunquote, encoding='latin1')
from http.cookies import SimpleCookie
- from collections import MutableMapping as DictMixin
+ if py310:
+ from _collections_abc import MutableMapping as DictMixin
+ else:
+ from collections import MutableMapping as DictMixin
import pickle
from io import BytesIO
from configparser import ConfigParser

View File

@ -17,12 +17,13 @@ if [ -d ${SOURCE_FILE} ]; then
rm -rf ${SOURCE_FILE}
fi
mkdir ${SOURCE_FILE}
tar -zxf $TAR_SOURCE_FILE -C $SOURCE_FILE --strip-components 1
tar -zxf $TAR_SOURCE_FILE -C $SOURCE_FILE --strip-components 1
cd $SOURCE_FILE
patch -p1 < ../0001-patch-repo.patch
patch -p1 < ../abovePython310.patch
python3 setup.py build
sed -i "s/scripts=/#scripts=/g" setup.py
python3 setup.py install --user
mkdir -p $TARGET_PATH
cp -r build/lib*/* $TARGET_PATH
touch $TARGET_PATH/__init__.py
touch $TARGET_PATH/__init__.py

View File

@ -25,7 +25,9 @@ echo "[cJSON] is " $use_tm
echo ------------------------------jemalloc---------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../jemalloc
python3 build.py -m all -t "release|debug" -f jemalloc-5.2.1.tar.gz >>../build/build_result.log
if [ "$ARCH"x != "loongarch64"x ];then
python3 build.py -m all -t "release|debug" -f jemalloc-5.2.1.tar.gz >>../build/build_result.log
fi
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[jemalloc] is " $use_tm
@ -39,7 +41,7 @@ echo "[libcgroup] is " $use_tm
echo ------------------------------numactl----------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../numactl
python3 build.py -m all -t "comm|llt" -f numactl-2.0.14.tar.gz >>../build/build_result.log
python3 build.py -m all -t "comm|llt" -f numactl-2.0.16.tar.gz >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[numactl] is " $use_tm
@ -67,7 +69,9 @@ echo "[iperf] is " $use_tm
echo -------------------------------llvm------------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../llvm
sh -x build.sh -m all -c comm >>../build/build_result.log
if [[ "$ARCH"x != "loongarch64"x ]];then
bash -x build.sh -m all -c comm >>../build/build_result.log
fi
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo $use_tm
@ -88,7 +92,7 @@ echo "[six] $use_tm"
echo -------------------------------ipaddres--------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../ipaddress
sh build.sh >>../build/demo.log
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[ipaddress] $use_tm"
@ -131,6 +135,13 @@ sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[bottle] $use_tm"
echo ---------------------------------tornado--------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../tornado
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[tornado] $use_tm"
echo -------------------------------------dmlc-core----------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../dmlc-core
@ -298,7 +309,9 @@ echo "[esdk_obs_api] $use_tm"
echo ---------------------------------------pljava-----------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../../dependency/pljava
sh build.sh -m build >>../build/build_result.log
if [[ "$ARCH"x != "loongarch64"x ]];then
bash build.sh -m build >>../build/build_result.log
fi
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[pljava] $use_tm"
@ -312,7 +325,9 @@ echo "[sqlparse] $use_tm"
echo ---------------------------------------masstree-----------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../masstree
sh build.sh >>../build/build_result.log
if [[ "$ARCH"x != "loongarch64"x ]];then
bash build.sh >>../build/build_result.log
fi
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[masstree] $use_tm"
@ -330,6 +345,13 @@ sh build.sh >> ../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[libevent] $use_tm"
echo ---------------------------------------aws-sdk-cpp------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../aws-sdk-cpp
sh build.sh >> ../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[aws-sdk-cpp] $use_tm"
# only copy
echo ----------------------------------------etcd-------------------------------------------

View File

@ -0,0 +1,22 @@
#!/bin/bash
version_list=("7 8 9 10")
ORIGIN_PATH=${PATH}
for version in ${version_list};
do
unset LD_LIBRARY_PATH
export PYTHONHOME=/usr/local/python3${version}
export LD_LIBRARY_PATH=$PYTHONHOME/lib:$LD_LIBRARY_PATH
export PATH=$PYTHONHOME/bin:${ORIGIN_PATH}
export DPYTHON_INCLUDE_PATH=$PYTHONHOME/include/python3.${version}
echo "++++++++++++++++++++++++++++++++++++++$(python3 -V)++++++++++++++++++++++++++++++++++++++++++++"
sh om_build_dependency.sh
if [ $? != 0 ]; then
echo "om dependency build failed.....python version: $(python3 -V)"
exit 1
fi
done

View File

@ -0,0 +1,155 @@
#!/bin/bash
# *************************************************************************
# Copyright: (c) Huawei Technologies Co., Ltd. 2020. All rights reserved
#
# description: the script that make install dependency
# date: 2020-10-21
# version: 1.0
# history:
#
# *************************************************************************
set -e
ARCH=$(uname -m)
ROOT_DIR="${PWD}/../.."
PLATFORM="$(bash ${ROOT_DIR}/build/get_PlatForm_str.sh)"
[ -f build_all.log ] && rm -rf build_all.log
echo --------------------------------openssl-------------------------------------------------
start_tm=$(date +%s%N)
[ -f build_result.log ] && rm -rf build_result.log
cd $(pwd)/../openssl
python3 build.py -m all -f openssl-OpenSSL_1_1_1n.tar.gz -t "comm|llt" >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[openssl] $use_tm"
echo -------------------------------asn1crypto-------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../asn1crypto
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[asn1crypto] $use_tm"
echo ---------------------------------six-----------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../six
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[six] $use_tm"
echo -------------------------------ipaddres--------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../ipaddress
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[ipaddress] $use_tm"
echo -------------------------------pycparser-------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../pycparser
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[pycparser] $use_tm"
echo ---------------------------------cffi----------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../cffi
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[cffi] $use_tm"
echo -------------------------------cryptography----------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../cryptography
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[cryptography] $use_tm"
echo ---------------------------------bcrypt--------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../bcrypt
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[bcrypt] $use_tm"
echo ---------------------------------bottle--------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../bottle
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[bottle] $use_tm"
echo ----------------------------------idna---------------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../idna
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[idna] $use_tm"
echo ----------------------------------netifaces----------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../netifaces
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[netifaces] $use_tm"
echo -------------------------------------paste-----------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../paste
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[paste] $use_tm"
echo -------------------------------------psutil----------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../psutil
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[psutil] $use_tm"
echo -------------------------------------pyasn1----------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../pyasn1
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[pyasn1] $use_tm"
echo --------------------------------------pynacl---------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../pynacl
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[pynacl] $use_tm"
echo -----------------------------------paramiko----------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../paramiko
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[paramiko] $use_tm"
echo --------------------------------------pyOpenSSL------------------------------------------
start_tm=$(date +%s%N)
cd $(pwd)/../pyOpenSSL
sh build.sh >>../build/build_result.log
end_tm=$(date +%s%N)
use_tm=$(echo $end_tm $start_tm | awk '{ print ($1 - $2) / 1000000000}' | xargs printf "%.2f")
echo "[pyOpenSSL] $use_tm"

View File

@ -0,0 +1,87 @@
diff -Naur a/cJSON.c b/cJSON.c
--- a/cJSON.c 2024-02-05 19:23:06.722566273 +0800
+++ b/cJSON.c 2024-02-05 19:22:33.685276776 +0800
@@ -401,7 +401,12 @@
{
char *copy = NULL;
/* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */
- if (!(object->type & cJSON_String) || (object->type & cJSON_IsReference))
+ if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference))
+ {
+ return NULL;
+ }
+ /* return NULL if the object is corrupted */
+ if (object->valuestring == NULL)
{
return NULL;
}
@@ -2260,7 +2265,7 @@
{
cJSON *after_inserted = NULL;
- if (which < 0)
+ if (which < 0 || newitem == NULL)
{
return false;
}
@@ -2271,6 +2276,11 @@
return add_item_to_array(array, newitem);
}
+ if (after_inserted != array->child && after_inserted->prev == NULL) {
+ /* return false if after_inserted is a corrupted array item */
+ return false;
+ }
+
newitem->next = after_inserted;
newitem->prev = after_inserted->prev;
after_inserted->prev = newitem;
diff -Naur a/tests/misc_tests.c b/tests/misc_tests.c
--- a/tests/misc_tests.c 2024-02-05 19:23:06.726566308 +0800
+++ b/tests/misc_tests.c 2024-02-05 19:22:33.689276811 +0800
@@ -353,6 +353,19 @@
{
char buffer[10];
cJSON *item = cJSON_CreateString("item");
+ cJSON *array = cJSON_CreateArray();
+ cJSON *item1 = cJSON_CreateString("item1");
+ cJSON *item2 = cJSON_CreateString("corrupted array item3");
+ cJSON *corruptedString = cJSON_CreateString("corrupted");
+ struct cJSON *originalPrev;
+
+ add_item_to_array(array, item1);
+ add_item_to_array(array, item2);
+
+ originalPrev = item2->prev;
+ item2->prev = NULL;
+ free(corruptedString->valuestring);
+ corruptedString->valuestring = NULL;
cJSON_InitHooks(NULL);
TEST_ASSERT_NULL(cJSON_Parse(NULL));
@@ -412,6 +425,8 @@
cJSON_DeleteItemFromObject(item, NULL);
cJSON_DeleteItemFromObjectCaseSensitive(NULL, "item");
cJSON_DeleteItemFromObjectCaseSensitive(item, NULL);
+ TEST_ASSERT_FALSE(cJSON_InsertItemInArray(array, 0, NULL));
+ TEST_ASSERT_FALSE(cJSON_InsertItemInArray(array, 1, item));
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(NULL, 0, item));
TEST_ASSERT_FALSE(cJSON_InsertItemInArray(item, 0, NULL));
TEST_ASSERT_FALSE(cJSON_ReplaceItemViaPointer(NULL, item, item));
@@ -428,10 +443,16 @@
TEST_ASSERT_NULL(cJSON_Duplicate(NULL, true));
TEST_ASSERT_FALSE(cJSON_Compare(item, NULL, false));
TEST_ASSERT_FALSE(cJSON_Compare(NULL, item, false));
+ TEST_ASSERT_NULL(cJSON_SetValuestring(NULL, "test"));
+ TEST_ASSERT_NULL(cJSON_SetValuestring(corruptedString, "test"));
cJSON_Minify(NULL);
/* skipped because it is only used via a macro that checks for NULL */
/* cJSON_SetNumberHelper(NULL, 0); */
+ /* restore corrupted item2 to delete it */
+ item2->prev = originalPrev;
+ cJSON_Delete(corruptedString);
+ cJSON_Delete(array);
cJSON_Delete(item);
}

View File

@ -0,0 +1,12 @@
diff -Naur a/cJSON.c b/cJSON.c
--- a/cJSON.c 2024-05-27 11:17:06.041240225 +0800
+++ b/cJSON.c 2024-05-27 11:19:35.927227504 +0800
@@ -406,7 +406,7 @@
return NULL;
}
/* return NULL if the object is corrupted */
- if (object->valuestring == NULL)
+ if (object->valuestring == NULL || valuestring == NULL)
{
return NULL;
}

View File

@ -38,6 +38,9 @@ function main()
fi
mkdir $SOURCE_CODE_PATH
tar -zxf $TAR_FILE_NAME -C $SOURCE_CODE_PATH --strip-components 1
cd ${LOCAL_DIR}/${SOURCE_CODE_PATH}
patch -p1 < ../CVE-2023-50471andCVE-2023-50472.patch
patch -p1 < ../CVE-2024-31755.patch
case "${BUILD_OPTION}" in
build)
build_component

View File

@ -4,4 +4,4 @@ def __bootstrap__():
__file__ = pkg_resources.resource_filename(__name__, '_cffi_backend.so')
__loader__ = None; del __bootstrap__, __loader__
imp.load_dynamic(__name__,__file__)
__bootstrap__()
__bootstrap__()

View File

@ -3,11 +3,14 @@
#sudo yum install -y libffi-devel
set -e
mkdir -p $(pwd)/../../output/install_tools
export TARGET_PATH=$(pwd)/../../output/install_tools/
export TARGET_PATH=$(pwd)/../../output/install_tools
export LD_LIBRARY_PATH=$TARGET_PATH:$LD_LIBRARY_PATH:/usr/lib64
export PATH=$TARGET_PATH:$PATH
export PYTHONPATH=$TARGET_PATH:$LIBRARY_PATH
version_list=("3.6" "3.7" "3.8" "3.9" "3.10" "3.11")
python_version=`python3 -V | awk -F ' ' '{print $2}' | awk -F '.' -v OFS='.' '{print $1,$2}'`
TAR_SOURCE_FILE=cffi-1.15.0.tar.gz
SOURCE_FILE=cffi-1.15.0
if [ -d ${SOURCE_FILE} ]; then
@ -20,6 +23,16 @@ CFLAGS='-fstack-protector-all' LDFLAGS='-Wl,-z,relro,-z,now -z,noexecstack' pyth
PYTHONHASHSEED=0 python3 setup.py install --user
cp -r build/lib*/* $TARGET_PATH
mv $TARGET_PATH/_cffi_backend.*.so $TARGET_PATH/_cffi_backend.so
cp -r $TARGET_PATH/_cffi_backend.so $TARGET_PATH/_cffi_backend.so_UCS4_$python_version
cp ./../_cffi_backend.py $TARGET_PATH/_cffi_backend.py
for version in ${version_list[@]}
do
if [ $version == $python_version ]; then
mkdir -p $TARGET_PATH/_cffi_backend_${version}
mv $TARGET_PATH/_cffi_backend.*.so $TARGET_PATH/_cffi_backend.so
cp $TARGET_PATH/_cffi_backend.so $TARGET_PATH/_cffi_backend_${version}/
cp $TARGET_PATH/_cffi_backend_${version}/_cffi_backend.so $TARGET_PATH/_cffi_backend.so_UCS4_$python_version
break
fi
done
cp ./../_cffi_backend.py $TARGET_PATH/_cffi_backend.py

View File

@ -0,0 +1,30 @@
diff -Naur a/src/cryptography/hazmat/backends/openssl/backend.py b/src/cryptography/hazmat/backends/openssl/backend.py
--- a/src/cryptography/hazmat/backends/openssl/backend.py 2023-12-02 16:06:27.029247885 +0800
+++ b/src/cryptography/hazmat/backends/openssl/backend.py 2023-12-02 16:03:19.239094195 +0800
@@ -2664,6 +2664,10 @@
_Reasons.UNSUPPORTED_SERIALIZATION,
)
+ certs: list[x509.Certificate] = []
+ if p7.d.sign == self._ffi.NULL:
+ return certs
+
sk_x509 = p7.d.sign.cert
num = self._lib.sk_X509_num(sk_x509)
certs = []
diff -Naur a/tests/hazmat/primitives/test_pkcs7.py b/tests/hazmat/primitives/test_pkcs7.py
--- a/tests/hazmat/primitives/test_pkcs7.py 2023-12-02 16:06:27.037247977 +0800
+++ b/tests/hazmat/primitives/test_pkcs7.py 2023-12-02 16:03:19.251094333 +0800
@@ -80,6 +80,12 @@
mode="rb",
)
+ def test_load_pkcs7_empty_certificates(self):
+ der = b"\x30\x0B\x06\x09\x2A\x86\x48\x86\xF7\x0D\x01\x07\x02"
+
+ certificates = pkcs7.load_der_pkcs7_certificates(der)
+ assert certificates == []
+
# We have no public verification API and won't be adding one until we get
# some requirements from users so this function exists to give us basic

View File

@ -0,0 +1,7 @@
def __bootstrap__():
global __bootstrap__, __loader__, __file__
import sys, pkg_resources, imp
__file__ = pkg_resources.resource_filename(__name__, '_openssl.abi3.so')
__loader__ = None; del __bootstrap__, __loader__
imp.load_dynamic(__name__,__file__)
__bootstrap__()

View File

@ -0,0 +1,7 @@
def __bootstrap__():
global __bootstrap__, __loader__, __file__
import sys, pkg_resources, imp
__file__ = pkg_resources.resource_filename(__name__, '_padding.abi3.so')
__loader__ = None; del __bootstrap__, __loader__
imp.load_dynamic(__name__,__file__)
__bootstrap__()

View File

@ -1,6 +1,7 @@
#!/bin/bash
# Copyright (c): 2012-2019, Huawei Tech. Co., Ltd.
set -e
ROOT_DIR=$(pwd)
mkdir -p $(pwd)/../python-lib
mkdir -p $(pwd)/../../output/install_tools
python_version=`python3 -V | awk -F ' ' '{print $2}' |awk -F '.' -v OFS='.' '{print $1,$2}'`
@ -15,10 +16,32 @@ if [ -d ${SOURCE_FILE} ]; then
rm -rf ${SOURCE_FILE}
fi
mkdir ${SOURCE_FILE}
version_num=("3.6" "3.7" "3.8" "3.9" "3.10" "3.11")
lib_dir=""
for (( i=0;i<${#version_num[*]};i++ ))
do
if [[ $(python3 -V | awk '{print $2}') =~ ${version_num[$i]} ]]; then
lib_dir="lib${version_num[$i]}"
break
fi
done
tar -zxf $TAR_SOURCE_FILE -C $SOURCE_FILE --strip-components 1
cd $SOURCE_FILE
patch -p1 < ../CVE-2023-49083.patch
CFLAGS='-fstack-protector-all' LDFLAGS='-Wl,-z,relro,-z,now -z,noexecstack' python3 setup.py build_ext --inplace --library-dirs=${OPENSSL_ROOT_DIR}/lib --include-dirs=${OPENSSL_ROOT_DIR}/include
python3 setup.py install --user
cp -r build/lib*/* $TARGET_PATH
preloader_dir_path=$(PYTHONPATH='' pip3 show cryptography | awk '/Location/{ print $2 }')
\cp -r ${preloader_dir_path}/cryptography/hazmat/bindings/_*.py $TARGET_PATH/cryptography/hazmat/bindings/
if [[ -d "$TARGET_PATH/cryptography/hazmat/bindings" ]]; then
mkdir -p $TARGET_PATH/cryptography/hazmat/bindings/$lib_dir
cp build/lib*/cryptography/hazmat/bindings/*.so $TARGET_PATH/cryptography/hazmat/bindings/$lib_dir
else
cp -r build/lib*/* $TARGET_PATH
mkdir -p $TARGET_PATH/cryptography/hazmat/bindings/$lib_dir
mv $TARGET_PATH/cryptography/hazmat/bindings/*.so $TARGET_PATH/cryptography/hazmat/bindings/$lib_dir
fi
cp $ROOT_DIR/_openssl.py $TARGET_PATH/cryptography/hazmat/bindings/
cp $ROOT_DIR/_padding.py $TARGET_PATH/cryptography/hazmat/bindings/

View File

@ -65,6 +65,9 @@ main()
cd ${SRC_DIR}
log "[Info] patching ......... "
patch -p1 < ../obs.patch >> $LOG_FILE 2>&1
if [[ "$ARCH"x = "loongarch64"x ]];then
cp -rf ${TRUNK_DIR}/build-aux/* ./platform/eSDK_LogAPI_V2.1.10/log4cpp/config/
fi
cd ..
cp Makefile huaweicloud-sdk-c-obs/platform/eSDK_LogAPI_V2.1.10/eSDKLogAPI/

View File

@ -25,7 +25,7 @@ g_PATH=build
NGHTTP_DIR=${TRUNK_DIR}/dependency/nghttp2/install_comm
LIBXML2_DIR=${TRUNK_DIR}/dependency/libxml2/install_comm
CURL_DIR=${TRUNK_DIR}/output/kernel/dependency/libcurl/comm
OPENSSL_DIR=${TRUNK_DIR}/output/kernrl/dependency/openssl/comm
OPENSSL_DIR=${TRUNK_DIR}/output/kernel/dependency/openssl/comm
PCRE_DIR=${TRUNK_DIR}/dependency/pcre/install_comm
LIBICONV_DIR=${TRUNK_DIR}/dependency/libiconv/install_comm
SECUREC_DIR=${TRUNK_DIR}/output/kernel/platform/Huawei_Secure_C/comm

View File

@ -5,14 +5,12 @@ mkdir -p $(pwd)/../../output/install_tools
export TARGET_PATH=$(pwd)/../../output/install_tools/
export LD_LIBRARY_PATH=$TARGET_PATH:$LD_LIBRARY_PATH
export PATH=$TARGET_PATH:$PATH
TAR_SOURCE_FILE=idna-2.10.tar.gz
SOURCE_FILE=idna-2.10
TAR_SOURCE_FILE=idna-3.7.tar.gz
SOURCE_FILE=idna-3.7
if [ -d ${SOURCE_FILE} ]; then
rm -rf ${SOURCE_FILE}
fi
mkdir ${SOURCE_FILE}
tar -zxf $TAR_SOURCE_FILE -C $SOURCE_FILE --strip-components 1
cd $SOURCE_FILE
python3 setup.py build
python3 setup.py install --user
cp -r build/lib*/* $TARGET_PATH
cp -r idna $TARGET_PATH

Binary file not shown.

View File

@ -10,6 +10,7 @@ TAR_SOURCE_FILE=ipaddress-1.0.22.tar.gz
SOURCE_FILE=ipaddress-1.0.22
tar zxvf $TAR_SOURCE_FILE
cd $SOURCE_FILE
patch -p1 < ../ipaddress-1.0.patch
python3 setup.py build
python3 setup.py install --user
cp -r build/lib*/* $TARGET_PATH

View File

@ -0,0 +1,20 @@
diff -crN '--exclude=.git' '--exclude=.gitee' '--exclude=.vscode' ipaddress-1.0.22/ipaddress.py ipaddress-1.0.22-v1.0/ipaddress.py
*** ipaddress-1.0.22/ipaddress.py 2018-04-16 02:00:41.000000000 +0800
--- ipaddress-1.0.22-v1.0/ipaddress.py 2023-10-26 19:51:58.044810776 +0800
***************
*** 1103,1109 ****
try:
# Always false if one is v4 and the other is v6.
if a._version != b._version:
! raise TypeError("%s and %s are not of the same version" (a, b))
return (b.network_address <= a.network_address and
b.broadcast_address >= a.broadcast_address)
except AttributeError:
--- 1103,1109 ----
try:
# Always false if one is v4 and the other is v6.
if a._version != b._version:
! raise TypeError("%s and %s are not of the same version" % (a, b))
return (b.network_address <= a.network_address and
b.broadcast_address >= a.broadcast_address)
except AttributeError:

View File

@ -130,7 +130,7 @@ class OPOperator():
add_pie_cmd2 = "cd %s/%s; sed -i 's/iperf3_LDFLAGS = -g/iperf3_LDFLAGS = -g -pie/' src/Makefile.in" % (self.local_dir, source_code_path)
ret = self.exe_cmd(add_pie_cmd2)
self.error_handler(ret, add_pie_cmd2)
config_cmd = "cd %s/%s; ./configure --prefix=%s/install_comm CFLAGS='-fstack-protector-all' LDFLAGS='-Wl,-z,relro,-z,now -z,noexecstack'" % (self.local_dir, source_code_path, self.local_dir)
config_cmd = "cd %s/%s; cp ../../../build-aux/config.* ./config/; ./configure --prefix=%s/install_comm CFLAGS='-fstack-protector-all' LDFLAGS='-Wl,-z,relro,-z,now -z,noexecstack'" % (self.local_dir, source_code_path, self.local_dir)
ret = self.exe_cmd(config_cmd)
self.error_handler(ret, config_cmd)
make_cmd = 'cd %s/%s; make && make install ' % (self.local_dir, source_code_path)

View File

@ -0,0 +1,35 @@
diff -Naur a/src/lib/kadm5/kadm_rpc_xdr.c b/src/lib/kadm5/kadm_rpc_xdr.c
--- a/src/lib/kadm5/kadm_rpc_xdr.c 2023-09-01 16:16:12.843658117 +0800
+++ b/src/lib/kadm5/kadm_rpc_xdr.c 2023-09-01 16:12:03.704811364 +0800
@@ -390,6 +390,7 @@
int v)
{
unsigned int n;
+ bool_t r;
if (!xdr_krb5_principal(xdrs, &objp->principal)) {
return (FALSE);
@@ -443,6 +444,9 @@
if (!xdr_krb5_int16(xdrs, &objp->n_key_data)) {
return (FALSE);
}
+ if (xdrs->x_op == XDR_DECODE && objp->n_key_data < 0) {
+ return (FALSE);
+ }
if (!xdr_krb5_int16(xdrs, &objp->n_tl_data)) {
return (FALSE);
}
@@ -451,9 +455,10 @@
return FALSE;
}
n = objp->n_key_data;
- if (!xdr_array(xdrs, (caddr_t *) &objp->key_data,
- &n, ~0, sizeof(krb5_key_data),
- xdr_krb5_key_data_nocontents)) {
+ r = xdr_array(xdrs, (caddr_t *) &objp->key_data, &n, objp->n_key_data,
+ sizeof(krb5_key_data), xdr_krb5_key_data_nocontents);
+ objp->n_key_data = n;
+ if (!r) {
return (FALSE);
}

View File

@ -0,0 +1,171 @@
From 548da160b52b25a106e9f6077d6a42c2c049586c Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Tue, 7 Mar 2023 00:19:33 -0500
Subject: [PATCH] Add a simple DER support header
Reference: https://github.com/krb5/krb5/commit/548da160b52b25a106e9f6077d6a42c2c049586c
Conflict: NA
---
src/include/k5-der.h | 149 +++++++++++++++++++++++++++++++++++++++++++
1 file changed, 149 insertions(+)
create mode 100644 src/include/k5-der.h
diff --git a/src/include/k5-der.h b/src/include/k5-der.h
new file mode 100644
index 0000000..b8371d9
--- /dev/null
+++ b/src/include/k5-der.h
@@ -0,0 +1,149 @@
+/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
+/* include/k5-der.h - Distinguished Encoding Rules (DER) declarations */
+/*
+ * Copyright (C) 2023 by the Massachusetts Institute of Technology.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
+ * OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * Most ASN.1 encoding and decoding is done using the table-driven framework in
+ * libkrb5. When that is not an option, these helpers can be used to encode
+ * and decode simple types.
+ */
+
+#ifndef K5_DER_H
+#define K5_DER_H
+
+#include <stdint.h>
+#include <stdbool.h>
+#include "k5-buf.h"
+#include "k5-input.h"
+
+/* Return the number of bytes needed to encode len as a DER encoding length. */
+static inline size_t
+k5_der_len_len(size_t len)
+{
+ size_t llen;
+
+ if (len < 128)
+ return 1;
+ llen = 1;
+ while (len > 0) {
+ len >>= 8;
+ llen++;
+ }
+ return llen;
+}
+
+/* Return the number of bytes needed to encode a DER value (with identifier
+ * byte and length) for a given contents length. */
+static inline size_t
+k5_der_value_len(size_t contents_len)
+{
+ return 1 + k5_der_len_len(contents_len) + contents_len;
+}
+
+/* Add a DER identifier byte (composed by the caller, including the ASN.1
+ * class, tag, and constructed bit) and length. */
+static inline void
+k5_der_add_taglen(struct k5buf *buf, uint8_t idbyte, size_t len)
+{
+ uint8_t *p;
+ size_t llen = k5_der_len_len(len);
+
+ p = k5_buf_get_space(buf, 1 + llen);
+ if (p == NULL)
+ return;
+ *p++ = idbyte;
+ if (len < 128) {
+ *p = len;
+ } else {
+ *p = 0x80 | (llen - 1);
+ /* Encode the length bytes backwards so the most significant byte is
+ * first. */
+ p += llen;
+ while (len > 0) {
+ *--p = len & 0xFF;
+ len >>= 8;
+ }
+ }
+}
+
+/* Add a DER value (identifier byte, length, and contents). */
+static inline void
+k5_der_add_value(struct k5buf *buf, uint8_t idbyte, const void *contents,
+ size_t len)
+{
+ k5_der_add_taglen(buf, idbyte, len);
+ k5_buf_add_len(buf, contents, len);
+}
+
+/*
+ * If the next byte in in matches idbyte and the subsequent DER length is
+ * valid, advance in past the value, set *contents_out to the value contents,
+ * and return true. Otherwise return false. Only set an error on in if the
+ * next bytes matches idbyte but the ensuing length is invalid. contents_out
+ * may be aliased to in; it will only be written to on successful decoding of a
+ * value.
+ */
+static inline bool
+k5_der_get_value(struct k5input *in, uint8_t idbyte,
+ struct k5input *contents_out)
+{
+ uint8_t lenbyte, i;
+ size_t len;
+ const void *bytes;
+
+ /* Do nothing if in is empty or the next byte doesn't match idbyte. */
+ if (in->status || in->len == 0 || *in->ptr != idbyte)
+ return false;
+
+ /* Advance past the identifier byte and decode the length. */
+ (void)k5_input_get_byte(in);
+ lenbyte = k5_input_get_byte(in);
+ if (lenbyte < 128) {
+ len = lenbyte;
+ } else {
+ len = 0;
+ for (i = 0; i < (lenbyte & 0x7F); i++) {
+ if (len > (SIZE_MAX >> 8)) {
+ k5_input_set_status(in, EOVERFLOW);
+ return false;
+ }
+ len = (len << 8) | k5_input_get_byte(in);
+ }
+ }
+
+ bytes = k5_input_get_bytes(in, len);
+ if (bytes == NULL)
+ return false;
+ k5_input_init(contents_out, bytes, len);
+ return true;
+}
+
+#endif /* K5_DER_H */
--
2.33.0

View File

@ -0,0 +1,536 @@
From b0a2f8a5365f2eec3e27d78907de9f9d2c80505a Mon Sep 17 00:00:00 2001
From: Greg Hudson <ghudson@mit.edu>
Date: Fri, 14 Jun 2024 10:56:12 -0400
Subject: [PATCH] Fix vulnerabilities in GSS message token handling
In gss_krb5int_unseal_token_v3() and gss_krb5int_unseal_v3_iov(),
verify the Extra Count field of CFX wrap tokens against the encrypted
header. Reported by Jacob Champion.
In gss_krb5int_unseal_token_v3(), check for a decrypted plaintext
length too short to contain the encrypted header and extra count
bytes. Reported by Jacob Champion.
In kg_unseal_iov_token(), separately track the header IOV length and
complete token length when parsing the token's ASN.1 wrapper. This
fix contains modified versions of functions from k5-der.h and
util_token.c; this duplication will be cleaned up in a future commit.
CVE-2024-37370:
In MIT krb5 release 1.3 and later, an attacker can modify the
plaintext Extra Count field of a confidential GSS krb5 wrap token,
causing the unwrapped token to appear truncated to the application.
CVE-2024-37371:
In MIT krb5 release 1.3 and later, an attacker can cause invalid
memory reads by sending message tokens with invalid length fields.
ticket: 9128 (new)
tags: pullup
target_version: 1.21-next
Reference: https://github.com/krb5/krb5/commit/b0a2f8a5365f2eec3e27d78907de9f9d2c80505a
Conflict: src/tests/gssapi/t_invalid.c
---
src/lib/gssapi/krb5/k5sealv3.c | 5 +
src/lib/gssapi/krb5/k5sealv3iov.c | 3 +-
src/lib/gssapi/krb5/k5unsealiov.c | 80 +++++++++-
src/tests/gssapi/t_invalid.c | 233 +++++++++++++++++++++++++-----
4 files changed, 275 insertions(+), 46 deletions(-)
diff --git a/src/lib/gssapi/krb5/k5sealv3.c b/src/lib/gssapi/krb5/k5sealv3.c
index e881eee..d3210c1 100644
--- a/src/lib/gssapi/krb5/k5sealv3.c
+++ b/src/lib/gssapi/krb5/k5sealv3.c
@@ -400,10 +400,15 @@ gss_krb5int_unseal_token_v3(krb5_context *contextptr,
/* Don't use bodysize here! Use the fact that
cipher.ciphertext.length has been adjusted to the
correct length. */
+ if (plain.length < 16 + ec) {
+ free(plain.data);
+ goto defective;
+ }
althdr = (unsigned char *)plain.data + plain.length - 16;
if (load_16_be(althdr) != KG2_TOK_WRAP_MSG
|| althdr[2] != ptr[2]
|| althdr[3] != ptr[3]
+ || load_16_be(althdr+4) != ec
|| memcmp(althdr+8, ptr+8, 8)) {
free(plain.data);
goto defective;
diff --git a/src/lib/gssapi/krb5/k5sealv3iov.c b/src/lib/gssapi/krb5/k5sealv3iov.c
index 333ee12..f8e90c3 100644
--- a/src/lib/gssapi/krb5/k5sealv3iov.c
+++ b/src/lib/gssapi/krb5/k5sealv3iov.c
@@ -402,9 +402,10 @@ gss_krb5int_unseal_v3_iov(krb5_context context,
if (load_16_be(althdr) != KG2_TOK_WRAP_MSG
|| althdr[2] != ptr[2]
|| althdr[3] != ptr[3]
+ || load_16_be(althdr + 4) != ec
|| memcmp(althdr + 8, ptr + 8, 8) != 0) {
*minor_status = 0;
- return GSS_S_BAD_SIG;
+ return GSS_S_DEFECTIVE_TOKEN;
}
} else {
/* Verify checksum: note EC is checksum size here, not padding */
diff --git a/src/lib/gssapi/krb5/k5unsealiov.c b/src/lib/gssapi/krb5/k5unsealiov.c
index 3ce2a90..6a6585d 100644
--- a/src/lib/gssapi/krb5/k5unsealiov.c
+++ b/src/lib/gssapi/krb5/k5unsealiov.c
@@ -25,6 +25,7 @@
*/
#include "k5-int.h"
+#include "k5-der.h"
#include "gssapiP_krb5.h"
static OM_uint32
@@ -247,6 +248,73 @@ cleanup:
return retval;
}
+/* Similar to k5_der_get_value(), but output an unchecked content length
+ * instead of a k5input containing the contents. */
+static inline bool
+get_der_tag(struct k5input *in, uint8_t idbyte, size_t *len_out)
+{
+ uint8_t lenbyte, i;
+ size_t len;
+
+ /* Do nothing if in is empty or the next byte doesn't match idbyte. */
+ if (in->status || in->len == 0 || *in->ptr != idbyte)
+ return false;
+
+ /* Advance past the identifier byte and decode the length. */
+ (void)k5_input_get_byte(in);
+ lenbyte = k5_input_get_byte(in);
+ if (lenbyte < 128) {
+ len = lenbyte;
+ } else {
+ len = 0;
+ for (i = 0; i < (lenbyte & 0x7F); i++) {
+ if (len > (SIZE_MAX >> 8)) {
+ k5_input_set_status(in, EOVERFLOW);
+ return false;
+ }
+ len = (len << 8) | k5_input_get_byte(in);
+ }
+ }
+
+ if (in->status)
+ return false;
+
+ *len_out = len;
+ return true;
+}
+
+/*
+ * Similar to g_verify_token_header() without toktype or flags, but do not read
+ * more than *header_len bytes of ASN.1 wrapper, and on output set *header_len
+ * to the remaining number of header bytes. Verify the outer DER tag's length
+ * against token_len, which may be larger (but not smaller) than *header_len.
+ */
+static gss_int32
+verify_detached_wrapper(const gss_OID_desc *mech, size_t *header_len,
+ uint8_t **header_in, size_t token_len)
+{
+ struct k5input in, mech_der;
+ gss_OID_desc toid;
+ size_t len;
+
+ k5_input_init(&in, *header_in, *header_len);
+
+ if (get_der_tag(&in, 0x60, &len)) {
+ if (len != token_len - (in.ptr - *header_in))
+ return G_BAD_TOK_HEADER;
+ if (!k5_der_get_value(&in, 0x06, &mech_der))
+ return G_BAD_TOK_HEADER;
+ toid.elements = (uint8_t *)mech_der.ptr;
+ toid.length = mech_der.len;
+ if (!g_OID_equal(&toid, mech))
+ return G_WRONG_MECH;
+ }
+
+ *header_in = (uint8_t *)in.ptr;
+ *header_len = in.len;
+ return 0;
+}
+
/*
* Caller must provide TOKEN | DATA | PADDING | TRAILER, except
* for DCE in which case it can just provide TOKEN | DATA (must
@@ -267,8 +335,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
gss_iov_buffer_t header;
gss_iov_buffer_t padding;
gss_iov_buffer_t trailer;
- size_t input_length;
- unsigned int bodysize;
+ size_t input_length, hlen;
int toktype2;
header = kg_locate_header_iov(iov, iov_count, toktype);
@@ -298,15 +365,14 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
input_length += trailer->buffer.length;
}
- code = g_verify_token_header(ctx->mech_used,
- &bodysize, &ptr, -1,
- input_length, 0);
+ hlen = header->buffer.length;
+ code = verify_detached_wrapper(ctx->mech_used, &hlen, &ptr, input_length);
if (code != 0) {
*minor_status = code;
return GSS_S_DEFECTIVE_TOKEN;
}
- if (bodysize < 2) {
+ if (hlen < 2) {
*minor_status = (OM_uint32)G_BAD_TOK_HEADER;
return GSS_S_DEFECTIVE_TOKEN;
}
@@ -314,7 +380,7 @@ kg_unseal_iov_token(OM_uint32 *minor_status,
toktype2 = load_16_be(ptr);
ptr += 2;
- bodysize -= 2;
+ hlen -= 2;
switch (toktype2) {
case KG2_TOK_MIC_MSG:
diff --git a/src/tests/gssapi/t_invalid.c b/src/tests/gssapi/t_invalid.c
index fb8fe55..d1f019f 100644
--- a/src/tests/gssapi/t_invalid.c
+++ b/src/tests/gssapi/t_invalid.c
@@ -36,31 +36,41 @@
*
* 1. A pre-CFX wrap or MIC token processed with a CFX-only context causes a
* null pointer dereference. (The token must use SEAL_ALG_NONE or it will
- * be rejected.)
+ * be rejected.) This vulnerability also applies to IOV unwrap.
*
- * 2. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
+ * 2. A CFX wrap token with a different value of EC between the plaintext and
+ * encrypted copies will be erroneously accepted, which allows a message
+ * truncation attack. This vulnerability also applies to IOV unwrap.
+ *
+ * 3. A CFX wrap token with a plaintext length fewer than 16 bytes causes an
+ * access before the beginning of the input buffer, possibly leading to a
+ * crash.
+ *
+ * 4. A CFX wrap token with a plaintext EC value greater than the plaintext
+ * length - 16 causes an integer underflow when computing the result length,
+ * likely causing a crash.
+ *
+ * 5. An IOV unwrap operation will overrun the header buffer if an ASN.1
+ * wrapper longer than the header buffer is present.
+ *
+ * 6. A pre-CFX wrap or MIC token with fewer than 24 bytes after the ASN.1
* header causes an input buffer overrun, usually leading to either a segv
* or a GSS_S_DEFECTIVE_TOKEN error due to garbage algorithm, filler, or
- * sequence number values.
+ * sequence number values. This vulnerability also applies to IOV unwrap.
*
- * 3. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
+ * 7. A pre-CFX wrap token with fewer than 16 + cksumlen bytes after the ASN.1
* header causes an integer underflow when computing the ciphertext length,
* leading to an allocation error on 32-bit platforms or a segv on 64-bit
* platforms. A pre-CFX MIC token of this size causes an input buffer
* overrun when comparing the checksum, perhaps leading to a segv.
*
- * 4. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
+ * 8. A pre-CFX wrap token with fewer than conflen + padlen bytes in the
* ciphertext (where padlen is the last byte of the decrypted ciphertext)
* causes an integer underflow when computing the original message length,
* leading to an allocation error.
*
- * 5. In the mechglue, truncated encapsulation in the initial context token can
+ * 9. In the mechglue, truncated encapsulation in the initial context token can
* cause input buffer overruns in gss_accept_sec_context().
- *
- * Vulnerabilities #1 and #2 also apply to IOV unwrap, although tokens with
- * fewer than 16 bytes after the ASN.1 header will be rejected.
- * Vulnerabilities #2 and #5 can only be robustly detected using a
- * memory-checking environment such as valgrind.
*/
#include "k5-int.h"
@@ -98,16 +108,24 @@ struct test {
};
/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key. */
+static void *
+ealloc(size_t len)
+{
+ void *ptr = calloc(len, 1);
+
+ if (ptr == NULL)
+ abort();
+ return ptr;
+}
+
+/* Fake up enough of a CFX GSS context for gss_unwrap, using an AES key.
+ * The context takes ownership of subkey. */
static gss_ctx_id_t
-make_fake_cfx_context()
+make_fake_cfx_context(krb5_key subkey)
{
gss_union_ctx_id_t uctx;
krb5_gss_ctx_id_t kgctx;
- krb5_keyblock kb;
-
- kgctx = calloc(1, sizeof(*kgctx));
- if (kgctx == NULL)
- abort();
+ kgctx = ealloc(sizeof(*kgctx));
kgctx->established = 1;
kgctx->proto = 1;
if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
@@ -116,15 +134,10 @@ make_fake_cfx_context()
kgctx->sealalg = -1;
kgctx->signalg = -1;
- kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
- kb.length = 16;
- kb.contents = (unsigned char *)"1234567887654321";
- if (krb5_k_create_key(NULL, &kb, &kgctx->subkey) != 0)
- abort();
+ kgctx->subkey = subkey;
+ kgctx->cksumtype = CKSUMTYPE_HMAC_SHA1_96_AES128;
- uctx = calloc(1, sizeof(*uctx));
- if (uctx == NULL)
- abort();
+ uctx = ealloc(sizeof(*uctx));
uctx->mech_type = &mech_krb5;
uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
return (gss_ctx_id_t)uctx;
@@ -138,9 +151,7 @@ make_fake_context(const struct test *test)
krb5_gss_ctx_id_t kgctx;
krb5_keyblock kb;
- kgctx = calloc(1, sizeof(*kgctx));
- if (kgctx == NULL)
- abort();
+ kgctx = ealloc(sizeof(*kgctx));
kgctx->established = 1;
if (g_seqstate_init(&kgctx->seqstate, 0, 0, 0, 0) != 0)
abort();
@@ -162,9 +173,7 @@ make_fake_context(const struct test *test)
if (krb5_k_create_key(NULL, &kb, &kgctx->enc) != 0)
abort();
- uctx = calloc(1, sizeof(*uctx));
- if (uctx == NULL)
- abort();
+ uctx = ealloc(sizeof(*uctx));
uctx->mech_type = &mech_krb5;
uctx->internal_ctx_id = (gss_ctx_id_t)kgctx;
return (gss_ctx_id_t)uctx;
@@ -194,9 +203,7 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out)
assert(mech_krb5.length == 9);
assert(len + 11 < 128);
- wrapped = malloc(len + 13);
- if (wrapped == NULL)
- abort();
+ wrapped = ealloc(len + 13);
wrapped[0] = 0x60;
wrapped[1] = len + 11;
wrapped[2] = 0x06;
@@ -207,6 +214,18 @@ make_token(unsigned char *token, size_t len, gss_buffer_t out)
out->value = wrapped;
}
+/* Create a 16-byte header for a CFX confidential wrap token to be processed by
+ * the fake CFX context. */
+static void
+write_cfx_header(uint16_t ec, uint8_t *out)
+{
+ memset(out, 0, 16);
+ store_16_be(KG2_TOK_WRAP_MSG, out);
+ out[2] = FLAG_WRAP_CONFIDENTIAL;
+ out[3] = 0xFF;
+ store_16_be(ec, out + 4);
+}
+
/* Unwrap a superficially valid RFC 1964 token with a CFX-only context, with
* regular and IOV unwrap. */
static void
@@ -238,6 +257,134 @@ test_bogus_1964_token(gss_ctx_id_t ctx)
free(in.value);
}
+static void
+test_cfx_altered_ec(gss_ctx_id_t ctx, krb5_key subkey)
+{
+ OM_uint32 major, minor;
+ uint8_t tokbuf[128], plainbuf[24];
+ krb5_data plain;
+ krb5_enc_data cipher;
+ gss_buffer_desc in, out;
+ gss_iov_buffer_desc iov[2];
+
+ /* Construct a header with a plaintext EC value of 3. */
+ write_cfx_header(3, tokbuf);
+
+ /* Encrypt a plaintext and a copy of the header with the EC value 0. */
+ memcpy(plainbuf, "truncate", 8);
+ memcpy(plainbuf + 8, tokbuf, 16);
+ store_16_be(0, plainbuf + 12);
+ plain = make_data(plainbuf, 24);
+ cipher.ciphertext.data = (char *)tokbuf + 16;
+ cipher.ciphertext.length = sizeof(tokbuf) - 16;
+ cipher.enctype = subkey->keyblock.enctype;
+ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
+ &plain, &cipher) != 0)
+ abort();
+
+ /* Verify that the token is rejected by gss_unwrap(). */
+ in.value = tokbuf;
+ in.length = 16 + cipher.ciphertext.length;
+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
+ if (major != GSS_S_DEFECTIVE_TOKEN)
+ abort();
+ (void)gss_release_buffer(&minor, &out);
+
+ /* Verify that the token is rejected by gss_unwrap_iov(). */
+ iov[0].type = GSS_IOV_BUFFER_TYPE_STREAM;
+ iov[0].buffer = in;
+ iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
+ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
+ if (major != GSS_S_DEFECTIVE_TOKEN)
+ abort();
+}
+
+static void
+test_cfx_short_plaintext(gss_ctx_id_t ctx, krb5_key subkey)
+{
+ OM_uint32 major, minor;
+ uint8_t tokbuf[128], zerobyte = 0;
+ krb5_data plain;
+ krb5_enc_data cipher;
+ gss_buffer_desc in, out;
+
+ write_cfx_header(0, tokbuf);
+
+ /* Encrypt a single byte, with no copy of the header. */
+ plain = make_data(&zerobyte, 1);
+ cipher.ciphertext.data = (char *)tokbuf + 16;
+ cipher.ciphertext.length = sizeof(tokbuf) - 16;
+ cipher.enctype = subkey->keyblock.enctype;
+ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
+ &plain, &cipher) != 0)
+ abort();
+
+ /* Verify that the token is rejected by gss_unwrap(). */
+ in.value = tokbuf;
+ in.length = 16 + cipher.ciphertext.length;
+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
+ if (major != GSS_S_DEFECTIVE_TOKEN)
+ abort();
+ (void)gss_release_buffer(&minor, &out);
+}
+
+static void
+test_cfx_large_ec(gss_ctx_id_t ctx, krb5_key subkey)
+{
+ OM_uint32 major, minor;
+ uint8_t tokbuf[128] = { 0 }, plainbuf[20];
+ krb5_data plain;
+ krb5_enc_data cipher;
+ gss_buffer_desc in, out;
+
+ /* Construct a header with an EC value of 5. */
+ write_cfx_header(5, tokbuf);
+
+ /* Encrypt a 4-byte plaintext plus the header. */
+ memcpy(plainbuf, "abcd", 4);
+ memcpy(plainbuf + 4, tokbuf, 16);
+ plain = make_data(plainbuf, 20);
+ cipher.ciphertext.data = (char *)tokbuf + 16;
+ cipher.ciphertext.length = sizeof(tokbuf) - 16;
+ cipher.enctype = subkey->keyblock.enctype;
+ if (krb5_k_encrypt(NULL, subkey, KG_USAGE_INITIATOR_SEAL, NULL,
+ &plain, &cipher) != 0)
+ abort();
+
+ /* Verify that the token is rejected by gss_unwrap(). */
+ in.value = tokbuf;
+ in.length = 16 + cipher.ciphertext.length;
+ major = gss_unwrap(&minor, ctx, &in, &out, NULL, NULL);
+ if (major != GSS_S_DEFECTIVE_TOKEN)
+ abort();
+ (void)gss_release_buffer(&minor, &out);
+}
+
+static void
+test_iov_large_asn1_wrapper(gss_ctx_id_t ctx)
+{
+ OM_uint32 minor, major;
+ uint8_t databuf[10] = { 0 };
+ gss_iov_buffer_desc iov[2];
+
+ /*
+ * In this IOV array, the header contains a DER tag with a dangling eight
+ * bytes of length field. The data IOV indicates a total token length
+ * sufficient to contain the length bytes.
+ */
+ iov[0].type = GSS_IOV_BUFFER_TYPE_HEADER;
+ iov[0].buffer.value = ealloc(2);
+ iov[0].buffer.length = 2;
+ memcpy(iov[0].buffer.value, "\x60\x88", 2);
+ iov[1].type = GSS_IOV_BUFFER_TYPE_DATA;
+ iov[1].buffer.value = databuf;
+ iov[1].buffer.length = 10;
+ major = gss_unwrap_iov(&minor, ctx, NULL, NULL, iov, 2);
+ if (major != GSS_S_DEFECTIVE_TOKEN)
+ abort();
+ free(iov[0].buffer.value);
+}
+
/* Process wrap and MIC tokens with incomplete headers. */
static void
test_short_header(gss_ctx_id_t ctx)
@@ -387,9 +534,7 @@ try_accept(void *value, size_t len)
gss_ctx_id_t ctx = GSS_C_NO_CONTEXT;
/* Copy the provided value to make input overruns more obvious. */
- in.value = malloc(len);
- if (in.value == NULL)
- abort();
+ in.value = ealloc(len);
memcpy(in.value, value, len);
in.length = len;
(void)gss_accept_sec_context(&minor, &ctx, GSS_C_NO_CREDENTIAL, &in,
@@ -424,11 +569,23 @@ test_short_encapsulation()
int
main(int argc, char **argv)
{
+ krb5_keyblock kb;
+ krb5_key cfx_subkey;
gss_ctx_id_t ctx;
size_t i;
- ctx = make_fake_cfx_context();
+ kb.enctype = ENCTYPE_AES128_CTS_HMAC_SHA1_96;
+ kb.length = 16;
+ kb.contents = (unsigned char *)"1234567887654321";
+ if (krb5_k_create_key(NULL, &kb, &cfx_subkey) != 0)
+ abort();
+
+ ctx = make_fake_cfx_context(cfx_subkey);
test_bogus_1964_token(ctx);
+ test_cfx_altered_ec(ctx, cfx_subkey);
+ test_cfx_short_plaintext(ctx, cfx_subkey);
+ test_cfx_large_ec(ctx, cfx_subkey);
+ test_iov_large_asn1_wrapper(ctx);
free_fake_context(ctx);
for (i = 0; i < sizeof(tests) / sizeof(*tests); i++) {
--
2.33.0

View File

@ -23,6 +23,7 @@ import subprocess
#--------------------------------------------------------#
source_code_path = "kerberos"
openssl_path = os.getcwd() + "/../../output/kernel/dependency/openssl/%s/%s"
class OPOperator():
def __init__(self, mode, filename, compiletype):
@ -122,6 +123,12 @@ class OPOperator():
patch_cmd = 'cd %s/%s; patch -p1 < ../%s' % (self.local_dir, source_code_path, pre_patch)
ret = self.exe_cmd(patch_cmd)
self.error_handler(ret)
status, output = subprocess.getstatusoutput('uname -m')
self.error_handler(status)
cpu_arch = output
if cpu_arch in ('loongarch64') :
ret = self.exe_cmd('cd %s/%s; cp -rf %s/../../build-aux/* ./src/config/' % (self.local_dir, source_code_path, self.local_dir))
self.error_handler(ret)
gen_cmd="cd %s/%s/src; rm configure; autoconf; autoheader; sed -i 's/lcom_err/lcom_err_gauss/g' configure" % (self.local_dir, source_code_path)
ret = self.exe_cmd(gen_cmd)
self.error_handler(ret)
@ -131,8 +138,10 @@ class OPOperator():
prepare_cmd = 'mkdir -p %s/install/comm' % (self.local_dir)
ret = self.exe_cmd(prepare_cmd)
self.error_handler(ret)
config_cmd = "cd %s/%s/src; ./configure --prefix=%s/install/comm LDFLAGS='-Wl,-z,relro,-z,now' CFLAGS='-fstack-protector-strong -fPIC' --disable-rpath --disable-pkinit --with-system-verto=no" % (self.local_dir, source_code_path, self.local_dir)
print("cd %s/%s/src; ./configure --prefix=%s/install/comm LDFLAGS='-Wl,-z,relro,-z,now' CFLAGS='-fstack-protector-strong -fPIC' --disable-rpath --disable-pkinit --with-system-verto=no" % (self.local_dir, source_code_path, self.local_dir))
openssl_comm_lib = (openssl_path % ("comm", "lib"))
openssl_comm_include = (openssl_path % ("comm", "include"))
config_cmd = "cd %s/%s/src; ./configure --prefix=%s/install/comm LDFLAGS='-Wl,-z,relro,-z,now -L%s' CFLAGS='-fstack-protector-strong -fPIC -I%s' --disable-rpath --disable-pkinit --with-system-verto=no" % (self.local_dir, source_code_path, self.local_dir, openssl_comm_lib, openssl_comm_include)
print(config_cmd)
ret = self.exe_cmd(config_cmd)
self.error_handler(ret)
make_cmd = 'cd %s/%s/src; make -j%s && make install' % (self.local_dir, source_code_path, cpu_num)
@ -142,8 +151,10 @@ class OPOperator():
prepare_cmd = 'mkdir -p %s/install/llt' % (self.local_dir)
ret = self.exe_cmd(prepare_cmd)
self.error_handler(ret)
config_cmd = "cd %s/%s/src; ./configure --prefix=%s/install/llt LDFLAGS='-Wl,-z,relro,-z,now' CFLAGS='-fstack-protector-strong -fPIC' --disable-rpath --disable-pkinit --with-system-verto=no" % (self.local_dir, source_code_path, self.local_dir)
print("cd %s/%s/src; ./configure --prefix=%s/install/llt LDFLAGS='-Wl,-z,relro,-z,now' CFLAGS='-fstack-protector-strong -fPIC' --disable-rpath --disable-pkinit --with-system-verto=no" % (self.local_dir, source_code_path, self.local_dir))
openssl_llt_lib = (openssl_path % ("llt", "lib"))
openssl_llt_include = (openssl_path % ("llt", "include"))
config_cmd = "cd %s/%s/src; ./configure --prefix=%s/install/llt LDFLAGS='-Wl,-z,relro,-z,now -L%s' CFLAGS='-fstack-protector-strong -fPIC -I%s' --disable-rpath --disable-pkinit --with-system-verto=no" % (self.local_dir, source_code_path, self.local_dir, openssl_llt_lib, openssl_llt_include)
print(config_cmd)
ret = self.exe_cmd(config_cmd)
self.error_handler(ret)
make_cmd = 'cd %s/%s/src; make -j%s && make install' % (self.local_dir, source_code_path, cpu_num)

View File

@ -0,0 +1,379 @@
diff -Naur a/lib/curl_rtmp.c b/lib/curl_rtmp.c
--- a/lib/curl_rtmp.c 2023-06-08 21:47:27.846551637 +0800
+++ b/lib/curl_rtmp.c 2023-06-08 21:49:43.748132707 +0800
@@ -229,7 +229,7 @@
/* We have to know if it's a write before we send the
* connect request packet
*/
- if(data->set.upload)
+ if(data->state.upload)
r->Link.protocol |= RTMP_FEATURE_WRITE;
/* For plain streams, use the buffer toggle trick to keep data flowing */
@@ -261,7 +261,7 @@
if(!RTMP_ConnectStream(r, 0))
return CURLE_FAILED_INIT;
- if(data->set.upload) {
+ if(data->state.upload) {
Curl_pgrsSetUploadSize(data, data->state.infilesize);
Curl_setup_transfer(data, -1, -1, FALSE, FIRSTSOCKET);
}
diff -Naur a/lib/file.c b/lib/file.c
--- a/lib/file.c 2023-06-08 21:47:27.846551637 +0800
+++ b/lib/file.c 2023-06-08 21:49:43.744132660 +0800
@@ -200,7 +200,7 @@
file->freepath = real_path; /* free this when done */
file->fd = fd;
- if(!data->set.upload && (fd == -1)) {
+ if(!data->state.upload && (fd == -1)) {
failf(data, "Couldn't open file %s", data->state.up.path);
file_done(data, CURLE_FILE_COULDNT_READ_FILE, FALSE);
return CURLE_FILE_COULDNT_READ_FILE;
@@ -382,7 +382,7 @@
Curl_pgrsStartNow(data);
- if(data->set.upload)
+ if(data->state.upload)
return file_upload(data);
file = data->req.p.file;
diff -Naur a/lib/ftp.c b/lib/ftp.c
--- a/lib/ftp.c 2023-06-08 21:47:27.850551682 +0800
+++ b/lib/ftp.c 2023-06-08 21:49:43.740132613 +0800
@@ -1381,7 +1381,7 @@
data->set.str[STRING_CUSTOMREQUEST]?
data->set.str[STRING_CUSTOMREQUEST]:
(data->state.list_only?"NLST":"LIST"));
- else if(data->set.upload)
+ else if(data->state.upload)
result = Curl_pp_sendf(data, &ftpc->pp, "PRET STOR %s",
conn->proto.ftpc.file);
else
@@ -3365,7 +3365,7 @@
/* the response code from the transfer showed an error already so no
use checking further */
;
- else if(data->set.upload) {
+ else if(data->state.upload) {
if((-1 != data->state.infilesize) &&
(data->state.infilesize != data->req.writebytecount) &&
!data->set.crlf &&
@@ -3637,7 +3637,7 @@
connected back to us */
}
}
- else if(data->set.upload) {
+ else if(data->state.upload) {
result = ftp_nb_type(data, conn, data->state.prefer_ascii,
FTP_STOR_TYPE);
if(result)
@@ -4217,7 +4217,7 @@
ftpc->file = NULL; /* instead of point to a zero byte,
we make it a NULL pointer */
- if(data->set.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) {
+ if(data->state.upload && !ftpc->file && (ftp->transfer == PPTRANSFER_BODY)) {
/* We need a file name when uploading. Return error! */
failf(data, "Uploading to a URL without a file name!");
free(rawPath);
diff -Naur a/lib/http.c b/lib/http.c
--- a/lib/http.c 2023-06-08 21:47:27.846551637 +0800
+++ b/lib/http.c 2023-06-08 21:49:43.748132707 +0800
@@ -2028,7 +2028,7 @@
Curl_HttpReq httpreq = data->state.httpreq;
const char *request;
if((conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_FTP)) &&
- data->set.upload)
+ data->state.upload)
httpreq = HTTPREQ_PUT;
/* Now set the 'request' pointer to the proper request string */
@@ -2343,7 +2343,7 @@
if((conn->handler->protocol & PROTO_FAMILY_HTTP) &&
(((httpreq == HTTPREQ_POST_MIME || httpreq == HTTPREQ_POST_FORM) &&
http->postsize < 0) ||
- ((data->set.upload || httpreq == HTTPREQ_POST) &&
+ ((data->state.upload || httpreq == HTTPREQ_POST) &&
data->state.infilesize == -1))) {
if(conn->bits.authneg)
/* don't enable chunked during auth neg */
diff -Naur a/lib/imap.c b/lib/imap.c
--- a/lib/imap.c 2023-06-08 21:47:27.842551592 +0800
+++ b/lib/imap.c 2023-06-08 21:54:45.259686242 +0800
@@ -1491,11 +1491,11 @@
result = status; /* use the already set error code */
}
else if(!data->set.connect_only && !imap->custom &&
- (imap->uid || imap->mindex || data->set.upload ||
+ (imap->uid || imap->mindex || data->state.upload ||
data->set.mimepost.kind != MIMEKIND_NONE)) {
/* Handle responses after FETCH or APPEND transfer has finished */
- if(!data->set.upload && data->set.mimepost.kind == MIMEKIND_NONE)
+ if(!data->state.upload && data->set.mimepost.kind == MIMEKIND_NONE)
state(data, IMAP_FETCH_FINAL);
else {
/* End the APPEND command first by sending an empty line */
@@ -1561,7 +1561,7 @@
selected = TRUE;
/* Start the first command in the DO phase */
- if(data->set.upload || data->set.mimepost.kind != MIMEKIND_NONE)
+ if(data->state.upload || data->set.mimepost.kind != MIMEKIND_NONE)
/* APPEND can be executed directly */
result = imap_perform_append(data);
else if(imap->custom && (selected || !imap->mailbox))
diff -Naur a/lib/rtsp.c b/lib/rtsp.c
--- a/lib/rtsp.c 2023-06-08 21:47:27.842551592 +0800
+++ b/lib/rtsp.c 2023-06-08 21:49:43.740132613 +0800
@@ -508,7 +508,7 @@
rtspreq == RTSPREQ_SET_PARAMETER ||
rtspreq == RTSPREQ_GET_PARAMETER) {
- if(data->set.upload) {
+ if(data->state.upload) {
putsize = data->state.infilesize;
data->state.httpreq = HTTPREQ_PUT;
@@ -527,7 +527,7 @@
result =
Curl_dyn_addf(&req_buffer,
"Content-Length: %" CURL_FORMAT_CURL_OFF_T"\r\n",
- (data->set.upload ? putsize : postsize));
+ (data->state.upload ? putsize : postsize));
if(result)
return result;
}
diff -Naur a/lib/setopt.c b/lib/setopt.c
--- a/lib/setopt.c 2023-06-08 22:22:59.219334893 +0800
+++ b/lib/setopt.c 2023-06-08 21:49:43.740132613 +0800
@@ -299,8 +299,8 @@
* We want to sent data to the remote host. If this is HTTP, that equals
* using the PUT request.
*/
- data->set.upload = (0 != va_arg(param, long)) ? TRUE : FALSE;
- if(data->set.upload) {
+ arg = va_arg(param, long);
+ if(arg) {
/* If this is HTTP, PUT is what's needed to "upload" */
data->set.method = HTTPREQ_PUT;
data->set.opt_no_body = FALSE; /* this is implied */
@@ -630,7 +630,6 @@
}
else
data->set.method = HTTPREQ_GET;
- data->set.upload = FALSE;
break;
case CURLOPT_HTTPPOST:
@@ -878,7 +877,6 @@
*/
if(va_arg(param, long)) {
data->set.method = HTTPREQ_GET;
- data->set.upload = FALSE; /* switch off upload */
data->set.opt_no_body = FALSE; /* this is implied */
}
break;
diff -Naur a/lib/smb.c b/lib/smb.c
--- a/lib/smb.c 2023-06-08 21:47:27.842551592 +0800
+++ b/lib/smb.c 2023-06-08 21:49:43.740132613 +0800
@@ -536,7 +536,7 @@
byte_count = strlen(req->path);
msg.name_length = smb_swap16((unsigned short)byte_count);
msg.share_access = smb_swap32(SMB_FILE_SHARE_ALL);
- if(data->set.upload) {
+ if(data->state.upload) {
msg.access = smb_swap32(SMB_GENERIC_READ | SMB_GENERIC_WRITE);
msg.create_disposition = smb_swap32(SMB_FILE_OVERWRITE_IF);
}
@@ -815,7 +815,7 @@
smb_m = (const struct smb_nt_create_response*) msg;
req->fid = smb_swap16(smb_m->fid);
data->req.offset = 0;
- if(data->set.upload) {
+ if(data->state.upload) {
data->req.size = data->state.infilesize;
Curl_pgrsSetUploadSize(data, data->req.size);
next_state = SMB_UPLOAD;
diff -Naur a/lib/smtp.c b/lib/smtp.c
--- a/lib/smtp.c 2023-06-08 21:47:27.842551592 +0800
+++ b/lib/smtp.c 2023-06-08 21:49:43.740132613 +0800
@@ -1387,7 +1387,7 @@
result = status; /* use the already set error code */
}
else if(!data->set.connect_only && data->set.mail_rcpt &&
- (data->set.upload || data->set.mimepost.kind)) {
+ (data->state.upload || data->set.mimepost.kind)) {
/* Calculate the EOB taking into account any terminating CRLF from the
previous line of the email or the CRLF of the DATA command when there
is "no mail data". RFC-5321, sect. 4.1.1.4.
@@ -1480,7 +1480,7 @@
smtp->eob = 2;
/* Start the first command in the DO phase */
- if((data->set.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
+ if((data->state.upload || data->set.mimepost.kind) && data->set.mail_rcpt)
/* MAIL transfer */
result = smtp_perform_mail(data);
else
diff -Naur a/lib/tftp.c b/lib/tftp.c
--- a/lib/tftp.c 2023-06-08 21:47:27.846551637 +0800
+++ b/lib/tftp.c 2023-06-08 21:49:43.740132613 +0800
@@ -367,7 +367,7 @@
/* tsize should be ignored on upload: Who cares about the size of the
remote file? */
- if(!data->set.upload) {
+ if(!data->state.upload) {
if(!tsize) {
failf(data, "invalid tsize -:%s:- value in OACK packet", value);
return CURLE_TFTP_ILLEGAL;
@@ -448,7 +448,7 @@
return result;
}
- if(data->set.upload) {
+ if(data->state.upload) {
/* If we are uploading, send an WRQ */
setpacketevent(&state->spacket, TFTP_EVENT_WRQ);
state->data->req.upload_fromhere =
@@ -483,7 +483,7 @@
if(!data->set.tftp_no_options) {
char buf[64];
/* add tsize option */
- if(data->set.upload && (data->state.infilesize != -1))
+ if(data->state.upload && (data->state.infilesize != -1))
msnprintf(buf, sizeof(buf), "%" CURL_FORMAT_CURL_OFF_T,
data->state.infilesize);
else
@@ -537,7 +537,7 @@
break;
case TFTP_EVENT_OACK:
- if(data->set.upload) {
+ if(data->state.upload) {
result = tftp_connect_for_tx(state, event);
}
else {
diff -Naur a/lib/transfer.c b/lib/transfer.c
--- a/lib/transfer.c 2023-06-08 21:47:27.842551592 +0800
+++ b/lib/transfer.c 2023-06-08 21:49:43.744132660 +0800
@@ -1391,6 +1391,7 @@
{
data->state.fread_func = data->set.fread_func_set;
data->state.in = data->set.in_set;
+ data->state.upload = (data->state.httpreq == HTTPREQ_PUT);
}
/*
@@ -1764,7 +1765,6 @@
data->state.httpreq != HTTPREQ_POST_MIME) ||
!(data->set.keep_post & CURL_REDIR_POST_303))) {
data->state.httpreq = HTTPREQ_GET;
- data->set.upload = false;
infof(data, "Switch to %s",
data->set.opt_no_body?"HEAD":"GET");
}
@@ -1802,7 +1802,7 @@
/* if we're talking upload, we can't do the checks below, unless the protocol
is HTTP as when uploading over HTTP we will still get a response */
- if(data->set.upload &&
+ if(data->state.upload &&
!(conn->handler->protocol&(PROTO_FAMILY_HTTP|CURLPROTO_RTSP)))
return CURLE_OK;
diff -Naur a/lib/urldata.h b/lib/urldata.h
--- a/lib/urldata.h 2023-06-08 21:47:27.846551637 +0800
+++ b/lib/urldata.h 2023-06-08 21:49:43.740132613 +0800
@@ -1473,6 +1473,7 @@
BIT(url_alloc); /* URL string is malloc()'ed */
BIT(referer_alloc); /* referer string is malloc()ed */
BIT(wildcard_resolve); /* Set to true if any resolve change is a wildcard */
+ BIT(upload); /* upload request */
};
/*
@@ -1815,7 +1816,6 @@
BIT(http_auto_referer); /* set "correct" referer when following
location: */
BIT(opt_no_body); /* as set with CURLOPT_NOBODY */
- BIT(upload); /* upload request */
BIT(verbose); /* output verbosity */
BIT(krb); /* Kerberos connection requested */
BIT(reuse_forbid); /* forbidden to be reused, close after use */
diff -Naur a/lib/vssh/libssh2.c b/lib/vssh/libssh2.c
--- a/lib/vssh/libssh2.c 2023-06-08 21:47:27.846551637 +0800
+++ b/lib/vssh/libssh2.c 2023-06-08 21:49:43.744132660 +0800
@@ -1840,7 +1840,7 @@
}
case SSH_SFTP_TRANS_INIT:
- if(data->set.upload)
+ if(data->state.upload)
state(data, SSH_SFTP_UPLOAD_INIT);
else {
if(sshp->path[strlen(sshp->path)-1] == '/')
@@ -2512,7 +2512,7 @@
break;
}
- if(data->set.upload) {
+ if(data->state.upload) {
if(data->state.infilesize < 0) {
failf(data, "SCP requires a known file size for upload");
sshc->actualcode = CURLE_UPLOAD_FAILED;
@@ -2652,7 +2652,7 @@
break;
case SSH_SCP_DONE:
- if(data->set.upload)
+ if(data->state.upload)
state(data, SSH_SCP_SEND_EOF);
else
state(data, SSH_SCP_CHANNEL_FREE);
diff -Naur a/lib/vssh/libssh.c b/lib/vssh/libssh.c
--- a/lib/vssh/libssh.c 2023-06-08 21:47:27.846551637 +0800
+++ b/lib/vssh/libssh.c 2023-06-08 21:49:43.744132660 +0800
@@ -1199,7 +1199,7 @@
}
case SSH_SFTP_TRANS_INIT:
- if(data->set.upload)
+ if(data->state.upload)
state(data, SSH_SFTP_UPLOAD_INIT);
else {
if(protop->path[strlen(protop->path)-1] == '/')
@@ -1812,7 +1812,7 @@
/* Functions from the SCP subsystem cannot handle/return SSH_AGAIN */
ssh_set_blocking(sshc->ssh_session, 1);
- if(data->set.upload) {
+ if(data->state.upload) {
if(data->state.infilesize < 0) {
failf(data, "SCP requires a known file size for upload");
sshc->actualcode = CURLE_UPLOAD_FAILED;
@@ -1917,7 +1917,7 @@
break;
}
case SSH_SCP_DONE:
- if(data->set.upload)
+ if(data->state.upload)
state(data, SSH_SCP_SEND_EOF);
else
state(data, SSH_SCP_CHANNEL_FREE);
diff -Naur a/lib/vssh/wolfssh.c b/lib/vssh/wolfssh.c
--- a/lib/vssh/wolfssh.c 2023-06-08 21:47:27.846551637 +0800
+++ b/lib/vssh/wolfssh.c 2023-06-08 21:49:43.744132660 +0800
@@ -553,7 +553,7 @@
}
break;
case SSH_SFTP_TRANS_INIT:
- if(data->set.upload)
+ if(data->state.upload)
state(data, SSH_SFTP_UPLOAD_INIT);
else {
if(sftp_scp->path[strlen(sftp_scp->path)-1] == '/')

View File

@ -0,0 +1,137 @@
From e478fb5f5f2e26e2b060a51939dd2746041459ab Mon Sep 17 00:00:00 2001
From: Jay Satiro <raysatiro@yahoo.com>
Date: Mon, 9 Oct 2023 16:34:27 -0400
Subject: [PATCH] socks: return error if hostname too long for remote resolve
Prior to this change the state machine attempted to change the remote
resolve to a local resolve if the hostname was longer than 255
characters. Unfortunately that did not work as intended and caused a
security issue.
This patch applies to curl versions 7.78.0 - 7.80.0. Other versions
that are affected take a different patch. Refer to the CVE advisory
for more information.
Bug: https://curl.se/docs/CVE-2023-38545.html
---
lib/socks.c | 8 +++---
tests/data/Makefile.inc | 2 +-
tests/data/test728 | 67 +++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 72 insertions(+), 5 deletions(-)
create mode 100644 tests/data/test728
diff --git a/lib/socks.c b/lib/socks.c
index 91c4223..222660c 100644
--- a/lib/socks.c
+++ b/lib/socks.c
@@ -535,9 +535,9 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
/* RFC1928 chapter 5 specifies max 255 chars for domain name in packet */
if(!socks5_resolve_local && hostname_len > 255) {
- infof(data, "SOCKS5: server resolving disabled for hostnames of "
- "length > 255 [actual len=%zu]", hostname_len);
- socks5_resolve_local = TRUE;
+ failf(data, "SOCKS5: the destination hostname is too long to be "
+ "resolved remotely by the proxy.");
+ return CURLPX_LONG_HOSTNAME;
}
if(auth & ~(CURLAUTH_BASIC | CURLAUTH_GSSAPI))
@@ -857,7 +857,7 @@ CURLproxycode Curl_SOCKS5(const char *proxy_user,
if(!socks5_resolve_local) {
socksreq[len++] = 3; /* ATYP: domain name = 3 */
- socksreq[len++] = (char) hostname_len; /* one byte address length */
+ socksreq[len++] = (unsigned char) hostname_len; /* one byte length */
memcpy(&socksreq[len], hostname, hostname_len); /* address w/o NULL */
len += hostname_len;
infof(data, "SOCKS5 connect to %s:%d (remotely resolved)",
diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc
index 1636969..1067005 100644
--- a/tests/data/Makefile.inc
+++ b/tests/data/Makefile.inc
@@ -94,7 +94,7 @@ test670 test671 test672 test673 test674 test675 test676 test677 test678 \
\
test700 test701 test702 test703 test704 test705 test706 test707 test708 \
test709 test710 test711 test712 test713 test714 test715 test716 test717 \
-test718 \
+test718 test728 \
\
test800 test801 test802 test803 test804 test805 test806 test807 test808 \
test809 test810 test811 test812 test813 test814 test815 test816 test817 \
diff --git a/tests/data/test728 b/tests/data/test728
new file mode 100644
index 0000000..8673613
--- /dev/null
+++ b/tests/data/test728
@@ -0,0 +1,67 @@
+<testcase>
+<info>
+<keywords>
+HTTP
+HTTP GET
+SOCKS5
+SOCKS5h
+followlocation
+</keywords>
+</info>
+
+#
+# Server-side
+<reply>
+# The hostname in this redirect is 256 characters and too long (> 255) for
+# SOCKS5 remote resolve. curl must return error CURLE_PROXY in this case.
+<data>
+HTTP/1.1 301 Moved Permanently
+Location: http://AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/
+Content-Length: 0
+Connection: close
+
+</data>
+</reply>
+
+#
+# Client-side
+<client>
+<features>
+proxy
+</features>
+<server>
+http
+socks5
+</server>
+ <name>
+SOCKS5h with HTTP redirect to hostname too long
+ </name>
+ <command>
+--no-progress-meter --location --proxy socks5h://%HOSTIP:%SOCKSPORT http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+#
+# Verify data after the test has been "shot"
+<verify>
+<strippart>
+s/\r\n$/\n/
+</strippart>
+<protocol>
+GET /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+User-Agent: curl/%VERSION
+Accept: */*
+
+</protocol>
+<errorcode>
+97
+</errorcode>
+# the error message is verified because error code CURLE_PROXY (97) may be
+# returned for any number of reasons and we need to make sure it is
+# specifically for the reason below so that we know the check is working.
+<stderr mode="text">
+curl: (97) SOCKS5: the destination hostname is too long to be resolved remotely by the proxy.
+</stderr>
+</verify>
+</testcase>
--
2.7.4

View File

@ -0,0 +1,35 @@
diff -Naur a/lib/cookie.c b/lib/cookie.c
--- a/lib/cookie.c 2023-12-18 10:05:27.017124540 +0800
+++ b/lib/cookie.c 2023-12-18 10:04:00.568115685 +0800
@@ -1026,15 +1026,23 @@
* dereference it.
*/
if(data && (domain && co->domain && !Curl_host_is_ipnum(co->domain))) {
- const psl_ctx_t *psl = Curl_psl_use(data);
- int acceptable;
-
- if(psl) {
- acceptable = psl_is_cookie_domain_acceptable(psl, domain, co->domain);
- Curl_psl_release(data);
+ bool acceptable = FALSE;
+ char lcase[256];
+ char lcookie[256];
+ size_t dlen = strlen(domain);
+ size_t clen = strlen(co->domain);
+ if((dlen < sizeof(lcase)) && (clen < sizeof(lcookie))) {
+ const psl_ctx_t *psl = Curl_psl_use(data);
+ if(psl) {
+ /* the PSL check requires lowercase domain name and pattern */
+ Curl_strntolower(lcase, domain, dlen + 1);
+ Curl_strntolower(lcookie, co->domain, clen + 1);
+ acceptable = psl_is_cookie_domain_acceptable(psl, lcase, lcookie);
+ Curl_psl_release(data);
+ }
+ else
+ acceptable = !bad_domain(domain, strlen(domain));
}
- else
- acceptable = !bad_domain(domain);
if(!acceptable) {
infof(data, "cookie '%s' dropped, domain '%s' must not "

View File

@ -0,0 +1,70 @@
diff -Naur a/lib/http2.c b/lib/http2.c
--- a/lib/http2.c 2024-04-13 14:42:27.209977032 +0800
+++ b/lib/http2.c 2024-04-13 14:33:11.606622746 +0800
@@ -547,6 +547,15 @@
return 0;
}
+static void free_push_headers(struct h2_stream_ctx *stream)
+{
+ size_t i;
+ for(i = 0; i<stream->push_headers_used; i++)
+ free(stream->push_headers[i]);
+ Curl_safefree(stream->push_headers);
+ stream->push_headers_used = 0;
+}
+
static int push_promise(struct Curl_easy *data,
struct connectdata *conn,
const nghttp2_push_promise *frame)
@@ -560,7 +569,6 @@
struct curl_pushheaders heads;
CURLMcode rc;
struct http_conn *httpc;
- size_t i;
/* clone the parent */
struct Curl_easy *newhandle = duphandle(data);
if(!newhandle) {
@@ -596,11 +604,7 @@
Curl_set_in_callback(data, false);
/* free the headers again */
- for(i = 0; i<stream->push_headers_used; i++)
- free(stream->push_headers[i]);
- free(stream->push_headers);
- stream->push_headers = NULL;
- stream->push_headers_used = 0;
+ free_push_headers(stream);
if(rv) {
DEBUGASSERT((rv > CURL_PUSH_OK) && (rv <= CURL_PUSH_ERROROUT));
@@ -1036,10 +1040,9 @@
stream->push_headers_alloc) {
char **headp;
stream->push_headers_alloc *= 2;
- headp = Curl_saferealloc(stream->push_headers,
- stream->push_headers_alloc * sizeof(char *));
+ headp = realloc(stream->push_headers, stream->push_headers_alloc * sizeof(char *));
if(!headp) {
- stream->push_headers = NULL;
+ free_push_headers(stream);
return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE;
}
stream->push_headers = headp;
@@ -1205,15 +1208,8 @@
setup */
Curl_dyn_free(&http->header_recvbuf);
Curl_dyn_free(&http->trailer_recvbuf);
- if(http->push_headers) {
- /* if they weren't used and then freed before */
- for(; http->push_headers_used > 0; --http->push_headers_used) {
- free(http->push_headers[http->push_headers_used - 1]);
- }
- free(http->push_headers);
- http->push_headers = NULL;
- }
+ free_push_headers(http);
if(!(data->conn->handler->protocol&PROTO_FAMILY_HTTP) ||
!httpc->h2) /* not HTTP/2 ? */
return;

View File

@ -120,6 +120,10 @@ main()
patch -p1 < ../CVE-2023-27535-1.patch >> $LOG_FILE 2>&1
patch -p1 < ../CVE-2023-27535-0.patch >> $LOG_FILE 2>&1
patch -p1 < ../CVE-2023-27536.patch >> $LOG_FILE 2>&1
patch -p1 < ../CVE-2023-28322.patch >> $LOG_FILE 2>&1
patch -p1 < ../CVE-2023-46218.patch >> $LOG_FILE 2>&1
patch -p1 < ../CVE-2023-38545.patch >> $LOG_FILE 2>&1
patch -p1 < ../CVE-2024-2398.patch >> $LOG_FILE 2>&1
checkret "Failed to patch huawei_curl.patch"
print_done
@ -128,7 +132,7 @@ main()
chmod a+x configure
log "[Info] configuring ...... "
./configure --prefix="$PREFIX_DIR" --with-ssl=$TRUNK_DIR/output/kernel/dependency/openssl/comm --without-libssh2 CFLAGS='-fstack-protector-strong -Wl,-z,relro,-z,now' --with-zlib=$TRUNK_DIR/output/kernel/dependency/zlib1.2.11/comm --with-gssapi_krb5_gauss-includes=$TRUNK_DIR/output/kernel/dependency/kerberos/comm/include --with-gssapi_krb5_gauss-libs=$TRUNK_DIR/output/kernel/dependency/kerberos/comm/lib >> $LOG_FILE 2>&1
./configure --prefix="$PREFIX_DIR" --disable-ldap --without-nghttp2 --with-ssl=$TRUNK_DIR/output/kernel/dependency/openssl/comm --without-libssh2 CFLAGS='-fstack-protector-strong -Wl,-z,relro,-z,now' --with-zlib=$TRUNK_DIR/output/kernel/dependency/zlib1.2.11/comm --with-gssapi_krb5_gauss-includes=$TRUNK_DIR/output/kernel/dependency/kerberos/comm/include --with-gssapi_krb5_gauss-libs=$TRUNK_DIR/output/kernel/dependency/kerberos/comm/lib >> $LOG_FILE 2>&1
checkret "Failed to configure libcurl."
print_done

View File

@ -8,7 +8,7 @@
# 2020-04-18 update libiconv-1.15 to libiconv-1.16
set -e
ARCH=`uname -m`
iconv_dir=$(pwd)/libiconv-1.16/
build_dir=$(pwd)/install_comm
@ -25,6 +25,10 @@ cd $iconv_dir
patch -p1 < ../libiconv.patch
chmod 777 configure
if [[ "$ARCH"x = "loongarch64"x ]];then
cp -rf $(pwd)/../../../build-aux/* ./build-aux/
cp -rf $(pwd)/../../../build-aux/* ./libcharset/build-aux/
fi
./configure CFLAGS='-fPIC -fstack-protector-all --param ssp-buffer-size=4 -Wstack-protector' CPPFLAGS='-fPIC -fstack-protector-all --param ssp-buffer-size=4 -Wstack-protector' LDFLAGS='-Wl,-z,relro,-z,now' --prefix=$build_dir --disable-rpath

View File

@ -0,0 +1,12 @@
diff -Naur a/xmlschemas.c b/xmlschemas.c
--- a/xmlschemas.c 2023-04-26 11:44:01.081847541 +0800
+++ b/xmlschemas.c 2023-04-26 11:48:01.812564661 +0800
@@ -18608,7 +18608,7 @@
"allowed to appear inside other model groups",
NULL, NULL);
- } else if (! dummySequence) {
+ } else if ((!dummySequence) && (baseType->subtypes != NULL)) {
xmlSchemaTreeItemPtr effectiveContent =
(xmlSchemaTreeItemPtr) type->subtypes;
/*

View File

@ -0,0 +1,12 @@
--- a/dict.c 2023-04-26 10:32:58.249262852 +0800
+++ b/dict.c 2023-04-26 10:35:00.362658956 +0800
@@ -451,7 +451,8 @@
xmlDictComputeFastKey(const xmlChar *name, int namelen, int seed) {
unsigned long value = seed;
- if (name == NULL) return(0);
+ if ((name == NULL) || (namelen <= 0))
+ return(value);
value += *name;
value <<= 5;
if (namelen > 10) {

View File

@ -0,0 +1,61 @@
diff -Naur a/tree.c b/tree.c
--- a/tree.c 2023-10-13 11:54:20.649358250 +0800
+++ b/tree.c 2023-10-13 11:49:51.522272604 +0800
@@ -4370,29 +4370,28 @@
xmlStaticCopyNodeList(xmlNodePtr node, xmlDocPtr doc, xmlNodePtr parent) {
xmlNodePtr ret = NULL;
xmlNodePtr p = NULL,q;
+ xmlDtdPtr newSubset = NULL;
while (node != NULL) {
-#ifdef LIBXML_TREE_ENABLED
if (node->type == XML_DTD_NODE ) {
- if (doc == NULL) {
+#ifdef LIBXML_TREE_ENABLED
+ if ((doc == NULL) || (doc->intSubset != NULL)) {
node = node->next;
continue;
}
- if (doc->intSubset == NULL) {
- q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
- if (q == NULL) return(NULL);
- q->doc = doc;
- q->parent = parent;
- doc->intSubset = (xmlDtdPtr) q;
- xmlAddChild(parent, q);
- } else {
- q = (xmlNodePtr) doc->intSubset;
- xmlAddChild(parent, q);
- }
- } else
+ q = (xmlNodePtr) xmlCopyDtd( (xmlDtdPtr) node );
+ if (q == NULL) goto error;
+ q->doc = doc;
+ q->parent = parent;
+ newSubset = (xmlDtdPtr) q;
+#else
+ node = node->next;
+ continue;
#endif /* LIBXML_TREE_ENABLED */
+ } else {
q = xmlStaticCopyNode(node, doc, parent, 1);
- if (q == NULL) return(NULL);
+ if (q == NULL) goto error;
+ }
if (ret == NULL) {
q->prev = NULL;
ret = p = q;
@@ -4404,7 +4403,13 @@
}
node = node->next;
}
+ if (newSubset != NULL)
+ doc->intSubset = newSubset;
return(ret);
+error:
+ xmlFreeNodeList(ret);
+ return(NULL);
+
}
/**

View File

@ -0,0 +1,11 @@
diff -Naur a/xmlreader.c b/xmlreader.c
--- a/xmlreader.c 2024-02-06 17:29:16.285516854 +0800
+++ b/xmlreader.c 2024-02-06 17:28:15.592980289 +0800
@@ -1586,6 +1586,7 @@
* Handle XInclude if asked for
*/
if ((reader->xinclude) && (reader->in_xinclude == 0) &&
+ (reader->state != XML_TEXTREADER_BACKTRACK) &&
(reader->node != NULL) &&
(reader->node->type == XML_ELEMENT_NODE) &&
(reader->node->ns != NULL) &&

View File

@ -0,0 +1,12 @@
diff -Naur a/xmllint.c b/xmllint.c
--- a/xmllint.c 2024-08-05 15:16:19.271124192 +0800
+++ b/xmllint.c 2024-08-05 15:20:00.325968893 +0800
@@ -602,7 +602,7 @@
len = strlen(buffer);
snprintf(&buffer[len], sizeof(buffer) - len, "\n");
cur = input->cur;
- while ((*cur == '\n') || (*cur == '\r'))
+ while ((cur > base) && ((*cur == '\n') || (*cur == '\r')))
cur--;
n = 0;
while ((cur != base) && (n++ < 80)) {

View File

@ -28,6 +28,11 @@ function build_component()
patch -p1 < ../libxml2.patch
patch -p1 < ../libxml2-CVE-2022-40303.patch
patch -p1 < ../libxml2-CVE-2022-40304.patch
patch -p1 < ../CVE-2023-28484.patch
patch -p1 < ../CVE-2023-29469.patch
patch -p1 < ../CVE-2023-45322.patch
patch -p1 < ../CVE-2024-25062.patch
patch -p1 < ../CVE-2024-34459.patch
tmp_cpus=$(grep -w processor /proc/cpuinfo|wc -l)
./autogen.sh
chmod +x configure

View File

@ -0,0 +1,116 @@
diff -Naur a/llvm/lib/Target/ARM/ARMFrameLowering.cpp b/llvm/lib/Target/ARM/ARMFrameLowering.cpp
--- a/llvm/lib/Target/ARM/ARMFrameLowering.cpp 2024-04-15 20:53:13.643344012 +0800
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.cpp 2024-04-15 21:13:51.463632273 +0800
@@ -1097,9 +1097,6 @@
// Fold the return instruction into the LDM.
DeleteRet = true;
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_RET : ARM::LDMIA_RET;
- // We 'restore' LR into PC so it is not live out of the return block:
- // Clear Restored bit.
- Info.setRestored(false);
} else
LdmOpc = AFI->isThumbFunction() ? ARM::t2LDMIA_UPD : ARM::LDMIA_UPD;
}
@@ -2155,6 +2152,35 @@
AFI->setLRIsSpilled(SavedRegs.test(ARM::LR));
}
+void ARMFrameLowering::updateLRRestored(MachineFunction &MF) {
+ MachineFrameInfo &MFI = MF.getFrameInfo();
+ if (!MFI.isCalleeSavedInfoValid())
+ return;
+ // Check if all terminators do not implicitly use LR. Then we can 'restore' LR
+ // into PC so it is not live out of the return block: Clear the Restored bit
+ // in that case.
+ for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
+ if (Info.getReg() != ARM::LR)
+ continue;
+ if (all_of(MF, [](const MachineBasicBlock &MBB) {
+ return all_of(MBB.terminators(), [](const MachineInstr &Term) {
+ return !Term.isReturn() || Term.getOpcode() == ARM::LDMIA_RET ||
+ Term.getOpcode() == ARM::t2LDMIA_RET ||
+ Term.getOpcode() == ARM::tPOP_RET;
+ });
+ })) {
+ Info.setRestored(false);
+ break;
+ }
+ }
+}
+
+void ARMFrameLowering::processFunctionBeforeFrameFinalized(
+ MachineFunction &MF, RegScavenger *RS) const {
+ TargetFrameLowering::processFunctionBeforeFrameFinalized(MF, RS);
+ updateLRRestored(MF);
+}
+
void ARMFrameLowering::getCalleeSaves(const MachineFunction &MF,
BitVector &SavedRegs) const {
TargetFrameLowering::getCalleeSaves(MF, SavedRegs);
diff -Naur a/llvm/lib/Target/ARM/ARMFrameLowering.h b/llvm/lib/Target/ARM/ARMFrameLowering.h
--- a/llvm/lib/Target/ARM/ARMFrameLowering.h 2024-04-15 20:53:13.643344012 +0800
+++ b/llvm/lib/Target/ARM/ARMFrameLowering.h 2024-04-15 21:13:51.463632273 +0800
@@ -58,6 +58,13 @@
void determineCalleeSaves(MachineFunction &MF, BitVector &SavedRegs,
RegScavenger *RS) const override;
+ /// Update the IsRestored flag on LR if it is spilled, based on the return
+ /// instructions.
+ static void updateLRRestored(MachineFunction &MF);
+
+ void processFunctionBeforeFrameFinalized(
+ MachineFunction &MF, RegScavenger *RS = nullptr) const override;
+
void adjustForSegmentedStacks(MachineFunction &MF,
MachineBasicBlock &MBB) const override;
diff -Naur a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp
--- a/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp 2024-04-15 20:53:13.643344012 +0800
+++ b/llvm/lib/Target/ARM/ARMLoadStoreOptimizer.cpp 2024-04-15 21:13:51.483632535 +0800
@@ -2037,19 +2037,6 @@
MO.setReg(ARM::PC);
PrevMI.copyImplicitOps(*MBB.getParent(), *MBBI);
MBB.erase(MBBI);
- // We now restore LR into PC so it is not live-out of the return block
- // anymore: Clear the CSI Restored bit.
- MachineFrameInfo &MFI = MBB.getParent()->getFrameInfo();
- // CSI should be fixed after PrologEpilog Insertion
- assert(MFI.isCalleeSavedInfoValid() && "CSI should be valid");
- for (CalleeSavedInfo &Info : MFI.getCalleeSavedInfo()) {
- if (Info.getReg() == ARM::LR) {
- Info.setRestored(false);
- break;
- }
- }
- return true;
- }
}
return false;
}
@@ -2095,16 +2082,24 @@
isThumb2 = AFI->isThumb2Function();
isThumb1 = AFI->isThumbFunction() && !isThumb2;
- bool Modified = false;
+ bool Modified = false, ModifiedLDMReturn = false;
for (MachineFunction::iterator MFI = Fn.begin(), E = Fn.end(); MFI != E;
++MFI) {
MachineBasicBlock &MBB = *MFI;
Modified |= LoadStoreMultipleOpti(MBB);
if (STI->hasV5TOps())
- Modified |= MergeReturnIntoLDM(MBB);
+ ModifiedLDMReturn |= MergeReturnIntoLDM(MBB);
if (isThumb1)
Modified |= CombineMovBx(MBB);
}
+ Modified |= ModifiedLDMReturn;
+
+ // If we merged a BX instruction into an LDM, we need to re-calculate whether
+ // LR is restored. This check needs to consider the whole function, not just
+ // the instruction(s) we changed, because there may be other BX returns which
+ // still need LR to be restored.
+ if (ModifiedLDMReturn)
+ ARMFrameLowering::updateLRRestored(Fn);
Allocator.DestroyAll();
return Modified;

View File

@ -23,6 +23,7 @@ function build_llvm()
mkdir ${SOURCE_CODE_PATH}
tar -zxf $TAR_FILE_NAME -C $SOURCE_CODE_PATH --strip-components 1
cd ${LOCAL_DIR}/${SOURCE_CODE_PATH}
patch -p1 < ../CVE-2024-31852.patch
# patch -p1 < ../0001-llvm.patch
# patch -p1 < ../0002-llvm.patch
# patch -p1 < ../0003-llvm.patch

View File

@ -1,955 +0,0 @@
From 0a2c88b6297fda231a5ca0f922bf732a8d0445dd Mon Sep 17 00:00:00 2001
From: Vinoth Veeraraghavan <vinoth.veeraraghavan@hotmail.com>
Date: Wed, 23 Mar 2022 19:09:26 +0700
Subject: [PATCH] Masstree OOM feature + bug fixes
More detail: 1. Feature: Add support for memory allocation failure
2. Bug fix: RCU\GC: delete node before disconnect
3. Bug fix: Leafs are marked as root by mistake
4. Bug fix: GC layer might access already freed node
5. Bug fix: Memory leak (Layers are not being removed)
6. Optimization: Disable some debug\unused code (collect new nodes)
7. Optimization: Disable phantom epoch support (not in use by MOT)
8. Optimization: Extend node version to 64bit
9. Optimization: Optimize leaf size to support larger internal ksuffix
---
kvthread.hh | 96 ++++++++++++++++++++++++++++++++-----
masstree.hh | 5 +-
masstree_insert.hh | 78 +++++++++++++++++++++++++++----
masstree_remove.hh | 17 +++++--
masstree_scan.hh | 4 +-
masstree_split.hh | 122 +++++++++++++++++++++++++++++++++++++++++++-----
masstree_struct.hh | 72 +++++++++++++++++++++-------
masstree_tcursor.hh | 31 ++++++------
mot_masstree_config.hpp | 11 ++++-
9 files changed, 365 insertions(+), 71 deletions(-)
diff --git a/kvthread.hh b/kvthread.hh
index 2c75e4e..364cd44 100644
--- a/kvthread.hh
+++ b/kvthread.hh
@@ -24,6 +24,48 @@
#include <pthread.h>
#include <sys/mman.h>
#include <stdlib.h>
+#include <vector>
+
+enum {
+ MT_MERR_OK = 0,
+ MT_MERR_MAKE_SPLIT_PRE_ALLOC = 1,
+ MT_MERR_MAKE_SPLIT_LEAF_ALLOC = 2,
+ MT_MERR_MAKE_NEW_LAYER_LEAF_ALLOC_1 = 3,
+ MT_MERR_MAKE_NEW_LAYER_LEAF_ALLOC_2 = 4,
+ MT_MERR_MAKE_NEW_LAYER_KSUFFIX_ALLOC_1 = 5,
+ MT_MERR_MAKE_NEW_LAYER_KSUFFIX_ALLOC_2 = 6,
+ MT_MERR_FIND_INSERT_ASSIGN_SUFFIX = 7,
+ MT_MERR_SPLIT_INTO_ASSIGN_INITALIZE_1 = 8,
+ MT_MERR_SPLIT_INTO_ASSIGN_INITALIZE_2 = 9,
+ MT_MERR_GC_LAYER_REMOVAL_MAKE = 10,
+ MT_MERR_MAKE_SPLIT_ASSIGN_SUFFIX = 11,
+ MT_MERR_MAKE_SPLIT_PERM_EXCHANGE = 12,
+
+ // Errors that are being handled internally (Operation should succeed even if last error contains them)
+ MT_MERR_NON_DISRUPTIVE_ERRORS = 15,
+
+ // We should not reach the following errors as they should be covered with other errors in more upper layer
+ MT_MERR_NOT_RETURNED_TO_USER_ERRORS = 20,
+ MT_MERR_ASSIGN_KSUF = 21,
+ MT_MERR_MAKE_LEAF = 22,
+ MT_MERR_MAKE_ROOT_LEAF = 23,
+ MT_MERR_MAKE_INTERNODE = 24,
+ MT_MERR_LEAF_ASSIGN = 25,
+ MT_MERR_ASSIGN_INITALIZE_1 = 26,
+ MT_MERR_ASSIGN_INITALIZE_2 = 27,
+
+ // We should not reach the following errors
+ MT_MERR_UNREACHABLE_ERRORS = 30,
+ MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED,
+ MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED_2,
+ MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED,
+ MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED_2,
+
+ MT_MERR_NOT_IN_USE_LAST_ENTRY = 40
+};
+
+#define MAX_ALLOC_ERROR_TYPES MT_MERR_NOT_IN_USE_LAST_ENTRY
+
class threadinfo;
class loginfo;
@@ -42,7 +84,7 @@ extern volatile mrcu_epoch_type globalepoch; // global epoch, updated regularly
extern volatile mrcu_epoch_type active_epoch;
// Memtags max allocation size
-#define MAX_MEMTAG_MASSTREE_LEAF_ALLOCATION_SIZE iceil(sizeof(leaf<P>) + 128, 64)
+#define MAX_MEMTAG_MASSTREE_LEAF_ALLOCATION_SIZE iceil(sizeof(leaf<P>) + 128, 64)
#define MAX_MEMTAG_MASSTREE_INTERNODE_ALLOCATION_SIZE sizeof(internode<P>)
#define MAX_MEMTAG_MASSTREE_LIMBO_GROUP_ALLOCATION_SIZE sizeof(mt_limbo_group)
@@ -117,6 +159,12 @@ class alignas(64) threadinfo {
TI_MAIN, TI_PROCESS, TI_LOG, TI_CHECKPOINT
};
+ typedef struct rcu_entry {
+ void* p;
+ size_t sz;
+ memtag tag;
+ } rcu_entry_t;
+
static threadinfo* allthreads;
threadinfo* next() const {
@@ -229,15 +277,14 @@ class alignas(64) threadinfo {
void deallocate_rcu(void* p, size_t sz, memtag tag) {
assert(p);
- memdebug::check_rcu(p, sz, tag);
- record_rcu(p, sz, tag);
- mark(threadcounter(tc_alloc + (tag > memtag_value)), -sz);
+ dealloc_rcu.push_back({p, sz, tag});
}
void* pool_allocate(size_t sz, memtag tag) {
void* p = NULL;
int nl = (sz + memdebug_size + CACHE_LINE_SIZE - 1) / CACHE_LINE_SIZE;
if (use_pool()) {
+ masstree_invariant(false); // mot code should not reach here
assert(nl <= pool_max_nlines);
if (unlikely(!pool_[nl - 1]))
refill_pool(nl);
@@ -264,17 +311,30 @@ class alignas(64) threadinfo {
*reinterpret_cast<void **>(p) = pool_[nl - 1];
pool_[nl - 1] = p;
} else
- free(p);
+ deallocate(p, sz, tag); // mot memory deallocation
mark(threadcounter(tc_alloc + (tag > memtag_value)),
-nl * CACHE_LINE_SIZE);
}
void pool_deallocate_rcu(void* p, size_t sz, memtag tag) {
- int nl = (sz + memdebug_size + CACHE_LINE_SIZE - 1) / CACHE_LINE_SIZE;
- assert(p && nl <= pool_max_nlines);
- memdebug::check_rcu(p, sz, memtag(tag + nl));
- record_rcu(p, sz, use_pool() ? memtag(tag + nl) : tag);
- mark(threadcounter(tc_alloc + (tag > memtag_value)),
- -nl * CACHE_LINE_SIZE);
+ if (unlikely(use_pool())) {
+ int nl = (sz + memdebug_size + CACHE_LINE_SIZE - 1) / CACHE_LINE_SIZE;
+ assert(p && nl <= pool_max_nlines);
+ memdebug::check_rcu(p, sz, memtag(tag + nl));
+ mark(threadcounter(tc_alloc + (tag > memtag_value)),
+ -nl * CACHE_LINE_SIZE);
+ dealloc_rcu.push_back({p, sz, memtag(tag + nl)});
+ } else {
+ dealloc_rcu.push_back({p, sz, tag});
+ }
+ }
+
+ void add_nodes_to_gc() {
+ for (uint32_t i = 0 ; i < dealloc_rcu.size() ; i++) {
+ masstree_invariant(dealloc_rcu[i].p);
+ record_rcu(dealloc_rcu[i].p, dealloc_rcu[i].sz, dealloc_rcu[i].tag);
+ dealloc_rcu[i].p = nullptr;
+ }
+ dealloc_rcu.clear();
}
// RCU
@@ -308,6 +368,11 @@ class alignas(64) threadinfo {
return pthreadid_;
}
+ inline void set_last_error(int error) { masstree_invariant(error < MT_MERR_UNREACHABLE_ERRORS); last_error = error; }
+ inline int get_last_error() { return last_error; }
+ inline bool non_disruptive_error() { return last_error == 0 ||
+ (last_error > MT_MERR_NON_DISRUPTIVE_ERRORS && last_error < MT_MERR_NOT_RETURNED_TO_USER_ERRORS); }
+
void report_rcu(void* ptr) const;
static void report_rcu_all(void* ptr);
static inline mrcu_epoch_type min_active_epoch();
@@ -333,8 +398,14 @@ class alignas(64) threadinfo {
#endif
}
+ bool is_empty_rcu_array() {
+ return dealloc_rcu.size() == 0;
+ }
+
private:
MOT::MasstreePrimaryIndex * cur_working_index;
+ int last_error = MT_MERR_OK;
+ std::vector<struct rcu_entry> dealloc_rcu;
union {
struct {
mrcu_epoch_type gc_epoch_;
@@ -386,7 +457,8 @@ class alignas(64) threadinfo {
void ng_record_rcu(void* ptr, int size, memtag tag);
void record_rcu(void* ptr, int size, memtag tag) {
- if (use_pool()) {
+ if (unlikely(use_pool())) {
+ masstree_invariant(false); // mot code should not reach here
if (limbo_tail_->tail_ + 2 > limbo_tail_->capacity)
refill_rcu();
uint64_t epoch = ng_getGlobalEpoch();
diff --git a/masstree.hh b/masstree.hh
index eaf6503..89af0ee 100644
--- a/masstree.hh
+++ b/masstree.hh
@@ -42,8 +42,8 @@ template <int LW = 15, int IW = LW> struct nodeparams {
static constexpr int bound_method = bound_method_fast;
static constexpr int debug_level = 0;
typedef uint64_t ikey_type;
- typedef uint32_t nodeversion_value_type;
- static constexpr bool need_phantom_epoch = true;
+ typedef uint64_t nodeversion_value_type;
+ static constexpr bool need_phantom_epoch = false;
typedef uint64_t phantom_epoch_type;
static constexpr ssize_t print_max_indent_depth = 12;
typedef key_unparse_printable_string key_unparse_type;
@@ -95,6 +95,7 @@ class basic_table {
inline node_type* root() const;
inline node_type* fix_root();
+ inline node_type** root_ref() { return &root_; }
bool get(Str key, value_type& value, threadinfo& ti) const;
diff --git a/masstree_insert.hh b/masstree_insert.hh
index 4a71942..e641f03 100644
--- a/masstree_insert.hh
+++ b/masstree_insert.hh
@@ -21,15 +21,18 @@
namespace Masstree {
template <typename P>
-bool tcursor<P>::find_insert(threadinfo& ti)
+bool tcursor<P>::find_insert(threadinfo& ti, bool & found)
{
+ found = false;
find_locked(ti);
original_n_ = n_;
original_v_ = n_->full_unlocked_version_value();
// maybe we found it
- if (state_)
+ if (state_) {
+ found = true;
return true;
+ }
// otherwise mark as inserted but not present
state_ = 2;
@@ -59,8 +62,11 @@ bool tcursor<P>::find_insert(threadinfo& ti)
1. If leaf is the most left leaf in the btree which means ikey0_[0] is not used as a boundary. (!n_->prev_)
2. If a new key, with ikey == ikey0_[0], is added. In this case, we can re-use slot 0 as we won't change the tree's structure. (n_->ikey_bound() == ka_.ikey()) */
if (likely(kx_.p != 0) || !n_->prev_ || n_->ikey_bound() == ka_.ikey()) {
- n_->assign(kx_.p, ka_, ti);
- return false;
+ // if n_->assign fails, we dont have enough space to place the suffix and we failed while allocating larger ksuffix.
+ bool res = n_->assign(kx_.p, ka_, ti);
+ if (!res)
+ ti.set_last_error(MT_MERR_FIND_INSERT_ASSIGN_SUFFIX);
+ return res;
}
}
@@ -78,8 +84,13 @@ bool tcursor<P>::make_new_layer(threadinfo& ti) {
// For each ikey_size bytes (currently 8) that matches in both key's suffixes, we will need to create a new layer
leaf_type* twig_head = n_;
leaf_type* twig_tail = n_;
+ leaf_type* nl = nullptr;
while (kcmp == 0) {
- leaf_type* nl = leaf_type::make_root(0, twig_tail, ti);
+ nl = leaf_type::make_root(0, twig_tail, ti);
+ if (!nl) {
+ ti.set_last_error(MT_MERR_MAKE_NEW_LAYER_LEAF_ALLOC_1);
+ goto make_new_layer_cleanup;
+ }
nl->assign_initialize_for_layer(0, oka);
if (twig_head != n_)
twig_tail->lv_[0] = nl;
@@ -87,7 +98,9 @@ bool tcursor<P>::make_new_layer(threadinfo& ti) {
twig_head = nl;
nl->permutation_ = permuter_type::make_sorted(1);
twig_tail = nl;
+#ifndef MOT_OBSOLETE_CODE
new_nodes_.emplace_back(nl, nl->full_unlocked_version_value());
+#endif
oka.shift();
ka_.shift();
// Compare the ikey only. if ikey matches and one or more of the suffixes != 0, compare using suffix size
@@ -102,9 +115,24 @@ bool tcursor<P>::make_new_layer(threadinfo& ti) {
+ n_->iksuf_[0].overhead(n_->width);
else
ksufsize = 0;
- leaf_type *nl = leaf_type::make_root(ksufsize, twig_tail, ti);
- nl->assign_initialize(0, kcmp < 0 ? oka : ka_, ti);
- nl->assign_initialize(1, kcmp < 0 ? ka_ : oka, ti);
+ nl = leaf_type::make_root(ksufsize, twig_tail, ti);
+ if (!nl) {
+ ti.set_last_error(MT_MERR_MAKE_NEW_LAYER_LEAF_ALLOC_2);
+ goto make_new_layer_cleanup;
+ }
+ // Even though the total ksuffix size was already provided to make_root, more memory might be allocated in assign_initialize calls
+ // as leaf internal suffix is bounded by 128 (+ 64 alignment).
+ // We will hit this issue (for sure) if ka_.suffix_length() + oka.suffix_length() > 192, but might hit it also when ka_.suffix_length() + oka.suffix_length() > 128.
+ if (!nl->assign_initialize(0, kcmp < 0 ? oka : ka_, ti)) {
+ ti.set_last_error(MT_MERR_MAKE_NEW_LAYER_KSUFFIX_ALLOC_1);
+ goto make_new_layer_cleanup;
+ }
+
+ if (!nl->assign_initialize(1, kcmp < 0 ? ka_ : oka, ti)) {
+ ti.set_last_error(MT_MERR_MAKE_NEW_LAYER_KSUFFIX_ALLOC_2);
+ goto make_new_layer_cleanup;
+ }
+
nl->lv_[kcmp > 0] = n_->lv_[kx_.p];
nl->lock(*nl, ti.lock_fence(tc_leaf_lock));
if (kcmp < 0)
@@ -134,6 +162,33 @@ bool tcursor<P>::make_new_layer(threadinfo& ti) {
n_->unlock();
n_ = nl;
kx_.i = kx_.p = kcmp < 0;
+ return true;
+
+make_new_layer_cleanup:
+ // n_ was not updated yet. It contains the original key (without any change). it will be unlocked later on (in lp.finish)
+ if (nl) {
+ // nl is not connected yet to twig_tail. handle it seperatly
+ nl->deallocate(ti);
+ nl = nullptr;
+ }
+
+ // Leafs in leaf list (starts from twig_head) has no suffix. In addition, they are not connected to the masstree yet, so we dont need to hold any locks.
+ if (twig_head != n_) {
+ while (twig_head) {
+ masstree_invariant(!twig_head->ksuf_);
+ masstree_invariant(twig_head->size() == 1);
+ masstree_invariant(twig_head->is_layer(0));
+ masstree_invariant(twig_head->stable_annotated(ti.stable_fence()).is_root());
+ leaf_type *next_layer_leaf = (leaf_type *)twig_head->lv_[0].layer();
+ twig_head->lv_[0] = nullptr;
+ // Remove it directly. no need to use rcu.
+ ti.deallocate(twig_head, sizeof(*twig_head) /* Being ignored */, memtag_masstree_leaf);
+ // Stop if we just finished to handle last leaf in list (twig_tail).
+ // Validating that next_layer_leaf != null wont work as twig_tail->lv_[0] == twig_tail.
+ twig_head = (twig_head == twig_tail) ? nullptr : next_layer_leaf;
+ }
+ }
+
return false;
}
@@ -152,15 +207,20 @@ inline void tcursor<P>::finish(int state, threadinfo& ti)
{
if (state < 0 && state_ == 1) {
if (finish_remove(ti))
- return;
+ goto clean_ti;
} else if (state > 0 && state_ == 2)
finish_insert();
// we finally know this!
if (n_ == original_n_)
updated_v_ = n_->full_unlocked_version_value();
+#ifndef MOT_OBSOLETE_CODE
else
new_nodes_.emplace_back(n_, n_->full_unlocked_version_value());
+#endif
n_->unlock();
+
+clean_ti:
+ ti.add_nodes_to_gc();
}
} // namespace Masstree
diff --git a/masstree_remove.hh b/masstree_remove.hh
index 5795261..a647ea5 100644
--- a/masstree_remove.hh
+++ b/masstree_remove.hh
@@ -144,8 +144,9 @@ void gc_layer_rcu_callback<P>::operator()(threadinfo& ti)
if (!do_remove || !lp.finish_remove(ti)) {
lp.n_->unlock();
}
- ti.deallocate(this, size(), memtag_masstree_gc);
}
+ ti.deallocate(this, size(), memtag_masstree_gc);
+ ti.add_nodes_to_gc();
}
template <typename P>
@@ -172,18 +173,18 @@ bool tcursor<P>::finish_remove(threadinfo& ti) {
if (perm.size()) {
return false;
} else {
- return remove_leaf(n_, root_, ka_.prefix_string(), ti);
+ return remove_leaf(n_, root_ref_, ka_.prefix_string(), ti);
}
}
template <typename P>
-bool tcursor<P>::remove_leaf(leaf_type* leaf, node_type* root,
+bool tcursor<P>::remove_leaf(leaf_type* leaf, node_type** root_ref,
Str prefix, threadinfo& ti)
{
if (!leaf->prev_) {
if (!leaf->next_.ptr && !prefix.empty()) {
// Leaf doesn't hold any keys, not in the highest layer and has no neighbors --> entire layer can be destroyed
- gc_layer_rcu_callback_ng<P>::make(root, prefix, ti);
+ gc_layer_rcu_callback_ng<P>::make(root_ref, prefix, ti);
}
// Leaf has neighbor to the right (next) or leaf in the highest layer. do nothing
return false;
@@ -211,6 +212,14 @@ bool tcursor<P>::remove_leaf(leaf_type* leaf, node_type* root,
// Unlink leaf from doubly-linked leaf list
btree_leaflink<leaf_type>::unlink(leaf);
+ // leaf->prev_ != NULL
+ leaf_type *prev = leaf->prev_;
+ if (!prev->prev_ && !prev->next_.ptr && prev->size() == 0 && !prefix.empty() ) {
+ // After removing the leaf, only the most left leaf remains (single leaf). We can remove the layer as the most left leaf
+ // doesn't hold any keys and layer is not the highest one.
+ gc_layer_rcu_callback_ng<P>::make(root_ref, prefix, ti);
+ }
+
// Remove leaf from tree, collapse trivial chains, and rewrite
// ikey bounds.
ikey_type ikey = leaf->ikey_bound();
diff --git a/masstree_scan.hh b/masstree_scan.hh
index 31ffcbc..f7b0937 100644
--- a/masstree_scan.hh
+++ b/masstree_scan.hh
@@ -306,8 +306,10 @@ int scanstackelt<P>::find_next(H &helper, key_type &ka, leafvalue_type &entry)
fence();
entry = n_->lv_[kp];
entry.prefetch(keylenx);
- if (n_->keylenx_has_ksuf(keylenx))
+ if (n_->keylenx_has_ksuf(keylenx)) {
keylen = ka.assign_store_suffix(n_->ksuf(kp));
+ masstree_invariant(keylen < (int)MASSTREE_MAXKEYLEN);
+ }
if (n_->has_changed(v_))
goto changed;
diff --git a/masstree_split.hh b/masstree_split.hh
index fcf35ee..42b012b 100644
--- a/masstree_split.hh
+++ b/masstree_split.hh
@@ -46,7 +46,7 @@ leaf<P>::ikey_after_insert(const permuter_type& perm, int i,
The split type is 0 if @a ka went into *this, 1 if the @a ka went into
*@a nr, and 2 for the sequential-order optimization (@a ka went into *@a
- nr and no other keys were moved). */
+ nr and no other keys were moved). if -1, split failed due to memory issue */
template <typename P>
int leaf<P>::split_into(leaf<P>* nr, tcursor<P>* cursor,
ikey_type& split_ikey, threadinfo& ti)
@@ -71,7 +71,8 @@ int leaf<P>::split_into(leaf<P>* nr, tcursor<P>* cursor,
int p = cursor->kx_.i;
if (p == 0 && !this->prev_) {
// reverse-sequential optimization
- mid = 1;
+ // We remove this optimization as it can lead us to empty leaf (In case insertion fails)
+ // mid = 1;
} else if (p == width && !this->next_.ptr) {
// sequential optimization
mid = width;
@@ -100,9 +101,16 @@ int leaf<P>::split_into(leaf<P>* nr, tcursor<P>* cursor,
typename permuter_type::value_type pv = perml.value_from(mid - (p < mid));
for (int x = mid; x <= width; ++x) {
if (x == p) {
- nr->assign_initialize(x - mid, cursor->ka_, ti);
+ if (!nr->assign_initialize(x - mid, cursor->ka_, ti)) {
+ ti.set_last_error(MT_MERR_SPLIT_INTO_ASSIGN_INITALIZE_1);
+ return -1;
+ }
+
} else {
- nr->assign_initialize(x - mid, this, pv & 15, ti);
+ if (!nr->assign_initialize(x - mid, this, pv & 15, ti)) {
+ ti.set_last_error(MT_MERR_SPLIT_INTO_ASSIGN_INITALIZE_2);
+ return -1;
+ }
pv >>= 4;
}
}
@@ -174,6 +182,14 @@ int internode<P>::split_into(internode<P>* nr, int p, ikey_type ka,
}
}
+template <typename P>
+void tcursor<P>::release_internodes(internode_type * internodes_array[], int start, int end, threadinfo& ti) {
+ for (int i = start; i < end; i++) {
+ masstree_invariant(internodes_array[i]);
+ ti.deallocate(internodes_array[i], sizeof(*internodes_array[i]) /* Being ignored */, memtag_masstree_internode);
+ internodes_array[i] = nullptr;
+ }
+}
template <typename P>
bool tcursor<P>::make_split(threadinfo& ti)
@@ -191,17 +207,66 @@ bool tcursor<P>::make_split(threadinfo& ti)
if (kx_.p != 0) {
n_->permutation_ = perm.value();
fence();
- n_->assign(kx_.p, ka_, ti);
+ if (n_->assign(kx_.p, ka_, ti)) {
+ return true;
+ }
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_PERM_EXCHANGE);
+ return false;
+ }
+ }
+
+ bool rc = true;
+
+ // 2 optimizations that can reduce the number of internodes allocations:
+ // 1. In n_ does not have parent, only 1 internode is required (rare case - only on first split)
+ // 2. In case n_'s parent has extra place, and it's height is 1, we dont need internodes at all (common case, but requires early lock of n_'s parent)
+ node_type* l_root = n_;
+
+ while (!l_root->is_root()) {
+ if (n_ != l_root) {
+ l_root->stable_annotated(ti.stable_fence());
+ }
+ l_root = l_root->maybe_parent();
+ }
+
+ // l_root->height_ is the layer real height or higher.
+ uint32_t layer_height = l_root->isleaf() ? 1 : ((internode_type *)l_root)->height_;
+ int reserved_nodes = layer_height + 5; // add 5 extra nodes (extra 5 layers in single b-tree)
+ internode_type * preallocated_internodes[reserved_nodes + 1] = { 0 };
+ int cur_cache_index = 0;
+
+ for (int i = 0; i < reserved_nodes; i++) {
+ preallocated_internodes[i] = (internode_type *)ti.pool_allocate(MAX_MEMTAG_MASSTREE_INTERNODE_ALLOCATION_SIZE,
+ memtag_masstree_internode);
+ if (!preallocated_internodes[i]) {
+ release_internodes(preallocated_internodes, 0, i, ti);
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_PRE_ALLOC);
return false;
}
}
node_type* child = leaf_type::make(n_->ksuf_used_capacity(), n_->phantom_epoch(), ti);
+ if (!child) {
+ release_internodes(preallocated_internodes, 0, reserved_nodes, ti);
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_LEAF_ALLOC);
+ return false;
+ }
child->assign_version(*n_);
+ child->mark_nonroot();
+ // As n_ is locked, child is locked as well.
ikey_type xikey[2];
// Add the new key and spread the keys between the 2 leafs. The new key might be inserted to either one of the leafs. Link to parent will be done later.
int split_type = n_->split_into(static_cast<leaf_type*>(child),
this, xikey[0], ti);
+
+ if (split_type < 0) {
+ // Split failed due to ksuffix memory allocation error (child is not connected to n_ at this stage)
+ release_internodes(preallocated_internodes, 0, reserved_nodes, ti);
+ // child is not visiable yet, so we can deallocate without rcu
+ ((leaf_type *)child)->deallocate(ti);
+ child = nullptr;
+ return false;
+ }
unsigned sense = 0;
node_type* n = n_;
uint32_t height = 0;
@@ -219,7 +284,17 @@ bool tcursor<P>::make_split(threadinfo& ti)
}
if (kp < 0 || p->height_ > height + 1) {
- internode_type *nn = internode_type::make(height + 1, ti);
+ masstree_invariant(preallocated_internodes[cur_cache_index]);
+ internode_type *nn = internode_type::make(height + 1, ti, preallocated_internodes[cur_cache_index++]);
+ if (!nn) {
+ // Should never happen with pre-allocated internodes. bad flow is not handled
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED);
+ }
+
+ if (cur_cache_index == reserved_nodes) {
+ // Should never happen with pre-allocated internodes (we should have enough reserved nodes). bad flow is not handled
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED);
+ }
nn->child_[0] = n;
nn->assign(0, xikey[sense], child);
nn->nkeys_ = 1;
@@ -233,11 +308,22 @@ bool tcursor<P>::make_split(threadinfo& ti)
n->set_parent(nn);
} else {
if (p->size() >= p->width) {
- next_child = internode_type::make(height + 1, ti);
+ masstree_invariant(preallocated_internodes[cur_cache_index]);
+ next_child = internode_type::make(height + 1, ti, preallocated_internodes[cur_cache_index++]);
+ if (!next_child) {
+ // Should never happen with pre-allocated internodes. bad flow is not handled
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED_2);
+ }
+
+ if (cur_cache_index == reserved_nodes) {
+ // Should never happen with pre-allocated internodes (we should have enough reserved nodes). bad flow is not handled
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED_2);
+ }
+
next_child->assign_version(*p);
next_child->mark_nonroot();
kp = p->split_into(next_child, kp, xikey[sense],
- child, xikey[sense ^ 1], split_type);
+ child, xikey[sense ^ 1], split_type); // No memory allocation
}
if (kp >= 0) {
p->shift_up(kp + 1, kp, p->size() - kp);
@@ -259,16 +345,27 @@ bool tcursor<P>::make_split(threadinfo& ti)
int width = perml.size();
perml.set_size(width - nr->size());
// removed item, if any, must be @ perml.size()
+ int perm_size = perml.size();
+ masstree_invariant(perm_size > 0); // Verify that the leaf is not empty
if (width != nl->width) {
- perml.exchange(perml.size(), nl->width - 1);
+ perml.exchange(perm_size, nl->width - 1);
}
nl->mark_split();
nl->permutation_ = perml.value();
// account for split
if (split_type == 0) {
kx_.p = perml.back();
- nl->assign(kx_.p, ka_, ti);
+
+ // In case the new inserted key should be placed in the origianl leaf (left leaf), memory allocation might be needed for it's ksuffix.
+ // If assign fails (--> memory allocation failure), the flow will continue, but we mark rc as false to indicate that the insertion failed.
+ // In this case, the key wont be exposed in finish_insert(), but the leaf split will be completed successfully.
+ if (!nl->assign(kx_.p, ka_, ti)) {
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_ASSIGN_SUFFIX);
+ rc = false;
+ }
+#ifndef MOT_OBSOLETE_CODE
new_nodes_.emplace_back(nr, nr->full_unlocked_version_value());
+#endif
} else {
kx_.i = kx_.p = kx_.i - perml.size();
n_ = nr;
@@ -296,7 +393,10 @@ bool tcursor<P>::make_split(threadinfo& ti)
}
}
- return false;
+ // Free unused pre-allocated internodes
+ release_internodes(preallocated_internodes, cur_cache_index, reserved_nodes, ti);
+
+ return rc;
}
} // namespace Masstree
diff --git a/masstree_struct.hh b/masstree_struct.hh
index 8f121a9..1b5d853 100644
--- a/masstree_struct.hh
+++ b/masstree_struct.hh
@@ -120,9 +120,15 @@ class internode : public node_base<P> {
: node_base<P>(false), nkeys_(0), height_(height), parent_() {
}
- static internode<P>* make(uint32_t height, threadinfo& ti) {
- void* ptr = ti.pool_allocate(MAX_MEMTAG_MASSTREE_INTERNODE_ALLOCATION_SIZE,
+ static internode<P>* make(uint32_t height, threadinfo& ti, void * allocated_internode = nullptr) {
+ void* ptr = allocated_internode ?
+ allocated_internode :
+ ti.pool_allocate(MAX_MEMTAG_MASSTREE_INTERNODE_ALLOCATION_SIZE,
memtag_masstree_internode);
+ if (!ptr) {
+ ti.set_last_error(MT_MERR_MAKE_INTERNODE);
+ return nullptr;
+ }
internode<P>* n = new(ptr) internode<P>(height);
assert(n);
if (P::debug_level > 0)
@@ -319,8 +325,12 @@ class leaf : public node_base<P> {
}
static leaf<P>* make(int ksufsize, phantom_epoch_type phantom_epoch, threadinfo& ti) {
- size_t sz = iceil(sizeof(leaf<P>) + std::min(ksufsize, 128), 64);
+ size_t sz = MAX_MEMTAG_MASSTREE_LEAF_ALLOCATION_SIZE; // iceil(sizeof(leaf<P>) + std::min(ksufsize, 128), 64);
void* ptr = ti.pool_allocate(sz, memtag_masstree_leaf);
+ if (!ptr) {
+ ti.set_last_error(MT_MERR_MAKE_LEAF);
+ return nullptr;
+ }
leaf<P>* n = new(ptr) leaf<P>(sz, phantom_epoch);
assert(n);
if (P::debug_level > 0) {
@@ -330,6 +340,10 @@ class leaf : public node_base<P> {
}
static leaf<P>* make_root(int ksufsize, leaf<P>* parent, threadinfo& ti) {
leaf<P>* n = make(ksufsize, parent ? parent->phantom_epoch() : phantom_epoch_type(), ti);
+ if (!n) {
+ ti.set_last_error(MT_MERR_MAKE_ROOT_LEAF);
+ return nullptr;
+ }
n->next_.ptr = n->prev_ = 0;
n->ikey0_[0] = 0; // to avoid undefined behavior
n->make_layer_root();
@@ -413,7 +427,9 @@ class leaf : public node_base<P> {
}
Str ksuf(int p, int keylenx) const {
(void) keylenx;
- masstree_precondition(keylenx_has_ksuf(keylenx));
+ // keylenx might not be equal to ksuf_keylenx as this operation might be called without holding leaf's lock
+ // We allow it, and expect the caller to validate leaf's version and retry.
+ //masstree_precondition(keylenx_has_ksuf(keylenx));
return ksuf_ ? ksuf_->get(p) : iksuf_[0].get(p);
}
Str ksuf(int p) const {
@@ -429,7 +445,7 @@ class leaf : public node_base<P> {
return s.len == ka.suffix().len
&& string_slice<uintptr_t>::equals_sloppy(s.s, ka.suffix().s, s.len);
}
- // Returns 1 if match & not layer, 0 if no match, <0 if match and layer
+ // Returns 1 if match & not layer, 0 if no match, < 0 if match and layer
int ksuf_matches(int p, const key_type& ka) const {
int keylenx = keylenx_[p];
if (keylenx < ksuf_keylenx)
@@ -520,40 +536,55 @@ class leaf : public node_base<P> {
modstate_ = modstate_deleted_layer;
}
- inline void assign(int p, const key_type& ka, threadinfo& ti) {
+ inline bool assign(int p, const key_type& ka, threadinfo& ti) {
lv_[p] = leafvalue_type::make_empty();
ikey0_[p] = ka.ikey();
if (!ka.has_suffix()) {
keylenx_[p] = ka.length();
} else {
keylenx_[p] = ksuf_keylenx;
- assign_ksuf(p, ka.suffix(), false, ti);
+ if (!assign_ksuf(p, ka.suffix(), false, ti)) {
+ ti.set_last_error(MT_MERR_LEAF_ASSIGN);
+ return false;
+ }
}
+
+ return true;
}
- inline void assign_initialize(int p, const key_type& ka, threadinfo& ti) {
+ inline bool assign_initialize(int p, const key_type& ka, threadinfo& ti) {
lv_[p] = leafvalue_type::make_empty();
ikey0_[p] = ka.ikey();
if (!ka.has_suffix()) {
keylenx_[p] = ka.length();
} else {
keylenx_[p] = ksuf_keylenx;
- assign_ksuf(p, ka.suffix(), true, ti);
+ if (!assign_ksuf(p, ka.suffix(), true, ti)) {
+ ti.set_last_error(MT_MERR_ASSIGN_INITALIZE_1);
+ return false;
+ }
}
+
+ return true;
}
- inline void assign_initialize(int p, leaf<P>* x, int xp, threadinfo& ti) {
+ inline bool assign_initialize(int p, leaf<P>* x, int xp, threadinfo& ti) {
lv_[p] = x->lv_[xp];
ikey0_[p] = x->ikey0_[xp];
keylenx_[p] = x->keylenx_[xp];
if (x->has_ksuf(xp)) {
- assign_ksuf(p, x->ksuf(xp), true, ti);
+ if (!assign_ksuf(p, x->ksuf(xp), true, ti)) {
+ ti.set_last_error(MT_MERR_ASSIGN_INITALIZE_2);
+ return false;
+ }
}
+
+ return true;
}
inline void assign_initialize_for_layer(int p, const key_type& ka) {
assert(ka.has_suffix());
ikey0_[p] = ka.ikey();
keylenx_[p] = layer_keylenx;
}
- void assign_ksuf(int p, Str s, bool initializing, threadinfo& ti);
+ bool assign_ksuf(int p, Str s, bool initializing, threadinfo& ti);
inline ikey_type ikey_after_insert(const permuter_type& perm, int i,
const tcursor<P>* cursor) const;
@@ -763,14 +794,14 @@ leaf<P>* leaf<P>::advance_to_key(const key_type& ka, nodeversion_type& v,
positions [0,p) are ready: keysuffixes in that range are copied. In either
case, the key at position p is NOT copied; it is assigned to @a s. */
template <typename P>
-void leaf<P>::assign_ksuf(int p, Str s, bool initializing, threadinfo& ti) {
+bool leaf<P>::assign_ksuf(int p, Str s, bool initializing, threadinfo& ti) {
if ((ksuf_ && ksuf_->assign(p, s))
|| (extrasize64_ > 0 && iksuf_[0].assign(p, s)))
{
#if !(defined(__x86_64__) || defined(__x86__))
fence();
-#endif
- return;
+#endif
+ return true;
}
external_ksuf_type* oksuf = ksuf_;
@@ -796,15 +827,19 @@ void leaf<P>::assign_ksuf(int p, Str s, bool initializing, threadinfo& ti) {
sz = std::max(sz, oksuf->capacity());
void* ptr = ti.allocate(sz, memtag_masstree_ksuffixes, &sz);
+ if (!ptr) {
+ ti.set_last_error(MT_MERR_ASSIGN_KSUF);
+ return false;
+ }
external_ksuf_type* nksuf = new(ptr) external_ksuf_type(width, sz);
for (int i = 0; i < n; ++i) {
int mp = initializing ? i : perm[i];
if (mp != p && has_ksuf(mp)) {
- bool ok = nksuf->assign(mp, ksuf(mp));
+ bool ok = nksuf->assign(mp, ksuf(mp)); // No memory allocation here
assert(ok); (void) ok;
}
}
- bool ok = nksuf->assign(p, s);
+ bool ok = nksuf->assign(p, s); // No memory allocation here
assert(ok); (void) ok;
fence();
@@ -824,11 +859,12 @@ void leaf<P>::assign_ksuf(int p, Str s, bool initializing, threadinfo& ti) {
if (oksuf)
ti.deallocate_rcu(oksuf, oksuf->capacity(),
memtag_masstree_ksuffixes);
+ return true;
}
template <typename P>
inline basic_table<P>::basic_table()
- : root_(0) {
+ : root_(nullptr) {
}
template <typename P>
diff --git a/masstree_tcursor.hh b/masstree_tcursor.hh
index 2442c9f..755588d 100644
--- a/masstree_tcursor.hh
+++ b/masstree_tcursor.hh
@@ -106,22 +106,23 @@ class tcursor {
static constexpr int new_nodes_size = 1; // unless we make a new trie newnodes will have at most 1 item
typedef small_vector<std::pair<leaf_type*, nodeversion_value_type>, new_nodes_size> new_nodes_type;
+#ifndef MOT_OBSOLETE_CODE
tcursor(basic_table<P>& table, Str str)
: ka_(str), root_(table.fix_root()) {
}
tcursor(basic_table<P>& table, const char* s, int len)
: ka_(s, len), root_(table.fix_root()) {
}
- tcursor(basic_table<P>& table, const unsigned char* s, int len)
- : ka_(reinterpret_cast<const char*>(s), len), root_(table.fix_root()) {
- }
- tcursor(node_base<P>* root, const char* s, int len)
- : ka_(s, len), root_(root) {
- }
tcursor(node_base<P>* root, const unsigned char* s, int len)
: ka_(reinterpret_cast<const char*>(s), len), root_(root) {
}
-
+#endif
+ tcursor(basic_table<P>& table, const unsigned char* s, int len)
+ : ka_(reinterpret_cast<const char*>(s), len), root_(table.fix_root()), root_ref_(table.root_ref()) {
+ }
+ tcursor(node_base<P>** root_ref, const char* s, int len)
+ : ka_(s, len), root_(*root_ref), root_ref_(root_ref) {
+ }
inline bool has_value() const {
return kx_.p >= 0;
}
@@ -148,13 +149,13 @@ class tcursor {
inline nodeversion_value_type updated_version_value() const {
return updated_v_;
}
-
+#ifndef MOT_OBSOLETE_CODE
inline const new_nodes_type &new_nodes() const {
return new_nodes_;
}
-
+#endif
inline bool find_locked(threadinfo& ti);
- inline bool find_insert(threadinfo& ti);
+ inline bool find_insert(threadinfo& ti, bool & found);
inline void finish(int answer, threadinfo& ti);
@@ -166,13 +167,16 @@ class tcursor {
key_type ka_;
key_indexed_position kx_;
node_base<P>* root_;
+ node_base<P>** root_ref_;
int state_;
- leaf_type* original_n_;
+ leaf_type* original_n_ = nullptr;
nodeversion_value_type original_v_;
nodeversion_value_type updated_v_;
- new_nodes_type new_nodes_;
+#ifndef MOT_OBSOLETE_CODE
+ new_nodes_type new_nodes_;
+#endif
inline node_type* reset_retry() {
ka_.unshift_all();
return root_;
@@ -180,6 +184,7 @@ class tcursor {
bool make_new_layer(threadinfo& ti);
bool make_split(threadinfo& ti);
+ void release_internodes(internode_type * internodes_array[], int start, int end, threadinfo& ti);
friend class leaf<P>;
inline void finish_insert();
inline bool finish_remove(threadinfo& ti);
@@ -191,7 +196,7 @@ class tcursor {
* If removing a leaf in layer 0, @a prefix is empty.
* If removing, for example, the node containing key "01234567ABCDEF" in the layer-1 tree
* rooted at "01234567", then @a prefix should equal "01234567". */
- static bool remove_leaf(leaf_type* leaf, node_type* root,
+ static bool remove_leaf(leaf_type* leaf, node_type** root_ref,
Str prefix, threadinfo& ti);
bool gc_layer(threadinfo& ti);
diff --git a/mot_masstree_config.hpp b/mot_masstree_config.hpp
index bec2ec8..fe3930b 100644
--- a/mot_masstree_config.hpp
+++ b/mot_masstree_config.hpp
@@ -25,6 +25,9 @@
#ifndef MOT_MASSTREE_CONFIG_HPP
#define MOT_MASSTREE_CONFIG_HPP
+// Ignore masstree code which is obsolete in MOT
+#define MOT_OBSOLETE_CODE 1
+
#define MOT_HAVE_CXX_TEMPLATE_ALIAS 1
#define MOT_HAVE_INT64_T_IS_LONG 1
#define MOT_HAVE_SIZE_T_IS_UNSIGNED_LONG 1
@@ -58,7 +61,7 @@
#define MOT_SIZEOF_LONG_LONG 8
#define MOT_SIZEOF_SHORT 2
#define MOT_WORDS_BIGENDIAN_SET 1
-
+/*
#define masstree_invariant(x, ...) \
do { \
} while (0)
@@ -66,6 +69,12 @@
#define masstree_precondition(x, ...) \
do { \
} while (0)
+*/
+
+#define masstree_invariant(x, ...) assert(x)
+#define masstree_precondition(x, ...) assert(x)
+
+
#ifndef invariant
#define invariant masstree_invariant
--
1.8.3.1

View File

@ -1,449 +0,0 @@
From 62fcebd4a8ac1a60acbf1f227a57be5b8d981c8e Mon Sep 17 00:00:00 2001
From: Vinoth Veeraraghavan <vinoth.veeraraghavan@hotmail.com>
Date: Thu, 14 Jul 2022 18:55:08 +0300
Subject: [PATCH] Clean masstree code
More detail: Clean masstree code
---
kvthread.hh | 27 +++--
masstree.hh | 15 +--
masstree_config.h | 118 +++++++++++----------
masstree_insert.hh | 4 +-
masstree_split.hh | 2 +-
masstree_tcursor.hh | 6 +-
mot_masstree_config.hpp | 99 -----------------
7 files changed, 83 insertions(+), 188 deletions(-)
delete mode 100644 mot_masstree_config.hpp
diff --git a/kvthread.hh b/kvthread.hh
index 364cd44..01d6919 100644
--- a/kvthread.hh
+++ b/kvthread.hh
@@ -69,11 +69,6 @@ enum {
class threadinfo;
class loginfo;
-namespace MOT
-{
- class MasstreePrimaryIndex;
- class GcManager;
-};
extern __thread threadinfo * mtSessionThreadInfo;
@@ -284,7 +279,7 @@ class alignas(64) threadinfo {
void* p = NULL;
int nl = (sz + memdebug_size + CACHE_LINE_SIZE - 1) / CACHE_LINE_SIZE;
if (use_pool()) {
- masstree_invariant(false); // mot code should not reach here
+ masstree_invariant(false); // internal memory pool is currently disabled
assert(nl <= pool_max_nlines);
if (unlikely(!pool_[nl - 1]))
refill_pool(nl);
@@ -308,10 +303,11 @@ class alignas(64) threadinfo {
assert(p && nl <= pool_max_nlines);
p = memdebug::check_free(p, sz, memtag(tag + nl));
if (use_pool()) {
+ masstree_invariant(false); // internal memory pool is currently disabled
*reinterpret_cast<void **>(p) = pool_[nl - 1];
pool_[nl - 1] = p;
} else
- deallocate(p, sz, tag); // mot memory deallocation
+ deallocate(p, sz, tag); // external memory pool deallocation
mark(threadcounter(tc_alloc + (tag > memtag_value)),
-nl * CACHE_LINE_SIZE);
}
@@ -380,15 +376,16 @@ class alignas(64) threadinfo {
void set_rcu_free_count(int rcu_count) { rcu_free_count = rcu_count; }
int get_rcu_free_count() { return rcu_free_count; }
- void set_gc_session(MOT::GcManager* gc_session);
- MOT::GcManager * get_gc_session();
+ void set_gc_session(void * gc_session);
+ void * get_gc_session();
inline uint32_t get_occupied_elements() { return total_limbo_inuse_elements; }
- void set_working_index (MOT::MasstreePrimaryIndex * index) { cur_working_index = (MOT::MasstreePrimaryIndex *)index; }
- MOT::MasstreePrimaryIndex * get_working_index () { return cur_working_index; }
+ void set_working_index (void * index) { cur_working_index = index; }
+ void * get_working_index () { return cur_working_index; }
- // This function is now used to defer between Masstree internal pools (use_pool == true) vs MOT pools\slab allocators (use_pool == false)
+ // This function is now used to defer between Masstree internal memory pool (use_pool == true) vs external memory pool (use_pool == false)
+ // Masstree internal memory pool is currently disabled
static bool use_pool() {
#if ENABLE_ASSERTIONS
return !no_pool_value;
@@ -403,7 +400,7 @@ class alignas(64) threadinfo {
}
private:
- MOT::MasstreePrimaryIndex * cur_working_index;
+ void * cur_working_index;
int last_error = MT_MERR_OK;
std::vector<struct rcu_entry> dealloc_rcu;
union {
@@ -427,7 +424,7 @@ class alignas(64) threadinfo {
int rcu_free_count;
mt_limbo_group* limbo_head_;
mt_limbo_group* limbo_tail_;
- MOT::GcManager* gc_session_;
+ void * gc_session_;
uint32_t total_limbo_inuse_elements;
mutable kvtimestamp_t ts_;
@@ -458,7 +455,7 @@ class alignas(64) threadinfo {
void record_rcu(void* ptr, int size, memtag tag) {
if (unlikely(use_pool())) {
- masstree_invariant(false); // mot code should not reach here
+ masstree_invariant(false); // internal memory pool is currently disabled
if (limbo_tail_->tail_ + 2 > limbo_tail_->capacity)
refill_rcu();
uint64_t epoch = ng_getGlobalEpoch();
diff --git a/masstree.hh b/masstree.hh
index 89af0ee..955a5bc 100644
--- a/masstree.hh
+++ b/masstree.hh
@@ -20,12 +20,6 @@
#include "ksearch.hh"
#include "kvthread.hh"
-namespace MOT {
-class Key;
-}
-
-using namespace MOT;
-
namespace Masstree {
using lcdf::Str;
using lcdf::String;
@@ -62,8 +56,7 @@ template <typename P> class basic_table;
template <typename P> class unlocked_tcursor;
template <typename P> class tcursor;
-template<bool CONST_ITERATOR, bool FORWARD, typename P>
-class MasstreeIterator;
+template <bool CONST_ITERATOR, bool FORWARD, typename P> class MasstreeIterator;
template <typename P>
class basic_table {
@@ -78,12 +71,12 @@ class basic_table {
typedef MasstreeIterator<false, true, P> ForwardIterator;
typedef MasstreeIterator<false, false, P> ReverseIterator;
- void find(MOT::Key const* const& key, void*& output, bool& result, const uint32_t& pid) const;
+ void find(const uint8_t* key, const uint32_t key_len, void*& output, bool& result, const uint32_t& pid) const;
- void iteratorScan(const char * keybuf, uint32_t keylen, const bool& matchKey, Iterator* const& it, const bool& forwardDirection,
+ void iteratorScan(const char * keybuf, uint32_t keylen, const bool& matchKey, void* const& it, const bool& forwardDirection,
bool& result, const uint32_t& pid);
- void *insert(MOT::Key const* const& key, void* const& entry, bool& result, const uint32_t& pid);
+ void *insert(const uint8_t* key, const uint32_t key_len, void* const& entry, bool& result, const uint32_t& pid);
void *remove(uint8_t const *const &key, uint32_t length, bool &result, const uint32_t &pid);
bool init(const uint16_t keyLength, const std::string& name, destroy_value_cb_func destroyValue_CB = NULL);
int getMemtagMaxSize(enum memtag tag);
diff --git a/masstree_config.h b/masstree_config.h
index ecfaf2b..d5a3a17 100644
--- a/masstree_config.h
+++ b/masstree_config.h
@@ -1,62 +1,66 @@
-/*
- * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
- *
- * openGauss 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.
- * -------------------------------------------------------------------------
- *
- * config.h
- * Masstree index configurations template.
- *
- * IDENTIFICATION
- * src/gausskernel/storage/mot/core/src/storage/index/masstree/config.h
- *
- * -------------------------------------------------------------------------
- */
-
-#include "mot_masstree_config.hpp"
-
#ifndef MASSTREE_CONFIG_H
#define MASSTREE_CONFIG_H
-#define HAVE_CXX_TEMPLATE_ALIAS MOT_HAVE_CXX_TEMPLATE_ALIAS
-#define HAVE_INT64_T_IS_LONG MOT_HAVE_INT64_T_IS_LONG
-#define HAVE_SIZE_T_IS_UNSIGNED_LONG MOT_HAVE_SIZE_T_IS_UNSIGNED_LONG
-#define HAVE_STD_HASH MOT_HAVE_STD_HASH
-#define HAVE_STD_IS_TRIVIALLY_COPYABLE MOT_HAVE_STD_IS_TRIVIALLY_COPYABLE
-#define HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE MOT_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
-#define HAVE_SUPERPAGE MOT_HAVE_SUPERPAGE
-#define HAVE_TYPE_TRAITS MOT_HAVE_TYPE_TRAITS
-#define HAVE_UNALIGNED_ACCESS MOT_HAVE_UNALIGNED_ACCESS
-#define HAVE___BUILTIN_CLZ MOT_HAVE___BUILTIN_CLZ
-#define HAVE___BUILTIN_CLZL MOT_HAVE___BUILTIN_CLZL
-#define HAVE___BUILTIN_CLZLL MOT_HAVE___BUILTIN_CLZLL
-#define HAVE___BUILTIN_CTZ MOT_HAVE___BUILTIN_CTZ
-#define HAVE___BUILTIN_CTZL MOT_HAVE___BUILTIN_CTZL
-#define HAVE___BUILTIN_CTZLL MOT_HAVE___BUILTIN_CTZLL
-#define HAVE___HAS_TRIVIAL_COPY MOT_HAVE___HAS_TRIVIAL_COPY
-#define HAVE___HAS_TRIVIAL_DESTRUCTOR MOT_HAVE___HAS_TRIVIAL_DESTRUCTOR
-#define HAVE___SYNC_BOOL_COMPARE_AND_SWAP MOT_HAVE___SYNC_BOOL_COMPARE_AND_SWAP
-#define HAVE___SYNC_BOOL_COMPARE_AND_SWAP_8 MOT_HAVE___SYNC_BOOL_COMPARE_AND_SWAP_8
-#define HAVE___SYNC_FETCH_AND_ADD MOT_HAVE___SYNC_FETCH_AND_ADD
-#define HAVE___SYNC_FETCH_AND_ADD_8 MOT_HAVE___SYNC_FETCH_AND_ADD_8
-#define HAVE___SYNC_FETCH_AND_OR MOT_HAVE___SYNC_FETCH_AND_OR
-#define HAVE___SYNC_FETCH_AND_OR_8 MOT_HAVE___SYNC_FETCH_AND_OR_8
-#define HAVE___SYNC_VAL_COMPARE_AND_SWAP MOT_HAVE___SYNC_VAL_COMPARE_AND_SWAP
-#define HAVE___SYNC_VAL_COMPARE_AND_SWAP_8 MOT_HAVE___SYNC_VAL_COMPARE_AND_SWAP_8
-#define MASSTREE_MAXKEYLEN MOT_MASSTREE_MAXKEYLEN
-#define SIZEOF_INT MOT_SIZEOF_INT
-#define SIZEOF_LONG MOT_SIZEOF_LONG
-#define SIZEOF_LONG_LONG MOT_SIZEOF_LONG_LONG
-#define SIZEOF_SHORT MOT_SIZEOF_SHORT
-#define WORDS_BIGENDIAN_SET MOT_WORDS_BIGENDIAN_SET
+#define HAVE_CXX_TEMPLATE_ALIAS 1
+#define HAVE_INT64_T_IS_LONG 1
+#define HAVE_SIZE_T_IS_UNSIGNED_LONG 1
+#define HAVE_STD_HASH 1
+#define HAVE_STD_IS_TRIVIALLY_COPYABLE 1
+#define HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1
+#define HAVE_SUPERPAGE 1
+#define HAVE_TYPE_TRAITS 1
+#define HAVE_UNALIGNED_ACCESS 0
+#define HAVE___BUILTIN_CLZ 1
+#define HAVE___BUILTIN_CLZL 1
+#define HAVE___BUILTIN_CLZLL 1
+#define HAVE___BUILTIN_CTZ 1
+#define HAVE___BUILTIN_CTZL 1
+#define HAVE___BUILTIN_CTZLL 1
+#define HAVE___HAS_TRIVIAL_COPY 1
+#define HAVE___HAS_TRIVIAL_DESTRUCTOR 1
+#define HAVE___SYNC_BOOL_COMPARE_AND_SWAP 1
+#define HAVE___SYNC_BOOL_COMPARE_AND_SWAP_8 1
+#define HAVE___SYNC_FETCH_AND_ADD 1
+#define HAVE___SYNC_FETCH_AND_ADD_8 1
+#define HAVE___SYNC_FETCH_AND_OR 1
+#define HAVE___SYNC_FETCH_AND_OR_8 1
+#define HAVE___SYNC_VAL_COMPARE_AND_SWAP 1
+#define HAVE___SYNC_VAL_COMPARE_AND_SWAP_8 1
+
+/* Maximum key length */
+#define MASSTREE_MAXKEYLEN 256U
+
+#define SIZEOF_INT 4
+#define SIZEOF_LONG 8
+#define SIZEOF_LONG_LONG 8
+#define SIZEOF_SHORT 2
+#define WORDS_BIGENDIAN_SET 1
+
+#define MASSTREE_OBSOLETE_CODE 1
+#define masstree_invariant(x, ...) assert(x)
+#define masstree_precondition(x, ...) assert(x)
+
+
+
+#ifndef invariant
+#define invariant masstree_invariant
+#endif
+#ifndef precondition
+#define precondition masstree_precondition
#endif
+
+#ifndef CACHE_LINE_SIZE
+#define CACHE_LINE_SIZE 64
+#endif
+
+#ifndef PRIu64
+#if HAVE_SIZE_T_IS_UNSIGNED_LONG_LONG
+#define PRIu64 "llu"
+#else
+#define PRIu64 "lu"
+#endif
+#endif
+
+
+#endif // MASSTREE_CONFIG_H
diff --git a/masstree_insert.hh b/masstree_insert.hh
index e641f03..9f21bca 100644
--- a/masstree_insert.hh
+++ b/masstree_insert.hh
@@ -98,7 +98,7 @@ bool tcursor<P>::make_new_layer(threadinfo& ti) {
twig_head = nl;
nl->permutation_ = permuter_type::make_sorted(1);
twig_tail = nl;
-#ifndef MOT_OBSOLETE_CODE
+#ifndef MASSTREE_OBSOLETE_CODE
new_nodes_.emplace_back(nl, nl->full_unlocked_version_value());
#endif
oka.shift();
@@ -213,7 +213,7 @@ inline void tcursor<P>::finish(int state, threadinfo& ti)
// we finally know this!
if (n_ == original_n_)
updated_v_ = n_->full_unlocked_version_value();
-#ifndef MOT_OBSOLETE_CODE
+#ifndef MASSTREE_OBSOLETE_CODE
else
new_nodes_.emplace_back(n_, n_->full_unlocked_version_value());
#endif
diff --git a/masstree_split.hh b/masstree_split.hh
index 42b012b..2d53de6 100644
--- a/masstree_split.hh
+++ b/masstree_split.hh
@@ -363,7 +363,7 @@ bool tcursor<P>::make_split(threadinfo& ti)
ti.set_last_error(MT_MERR_MAKE_SPLIT_ASSIGN_SUFFIX);
rc = false;
}
-#ifndef MOT_OBSOLETE_CODE
+#ifndef MASSTREE_OBSOLETE_CODE
new_nodes_.emplace_back(nr, nr->full_unlocked_version_value());
#endif
} else {
diff --git a/masstree_tcursor.hh b/masstree_tcursor.hh
index 755588d..73231b8 100644
--- a/masstree_tcursor.hh
+++ b/masstree_tcursor.hh
@@ -106,7 +106,7 @@ class tcursor {
static constexpr int new_nodes_size = 1; // unless we make a new trie newnodes will have at most 1 item
typedef small_vector<std::pair<leaf_type*, nodeversion_value_type>, new_nodes_size> new_nodes_type;
-#ifndef MOT_OBSOLETE_CODE
+#ifndef MASSTREE_OBSOLETE_CODE
tcursor(basic_table<P>& table, Str str)
: ka_(str), root_(table.fix_root()) {
}
@@ -149,7 +149,7 @@ class tcursor {
inline nodeversion_value_type updated_version_value() const {
return updated_v_;
}
-#ifndef MOT_OBSOLETE_CODE
+#ifndef MASSTREE_OBSOLETE_CODE
inline const new_nodes_type &new_nodes() const {
return new_nodes_;
}
@@ -174,7 +174,7 @@ class tcursor {
nodeversion_value_type original_v_;
nodeversion_value_type updated_v_;
-#ifndef MOT_OBSOLETE_CODE
+#ifndef MASSTREE_OBSOLETE_CODE
new_nodes_type new_nodes_;
#endif
inline node_type* reset_retry() {
diff --git a/mot_masstree_config.hpp b/mot_masstree_config.hpp
deleted file mode 100644
index fe3930b..0000000
--- a/mot_masstree_config.hpp
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (c) 2020 Huawei Technologies Co.,Ltd.
- *
- * openGauss 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.
- * -------------------------------------------------------------------------
- *
- * mot_masstree_config.hpp
- * MOT configurations for Masstree index.
- *
- * IDENTIFICATION
- * src/gausskernel/storage/mot/core/src/storage/index/masstree/mot_masstree_config.hpp
- *
- * -------------------------------------------------------------------------
- */
-
-#ifndef MOT_MASSTREE_CONFIG_HPP
-#define MOT_MASSTREE_CONFIG_HPP
-
-// Ignore masstree code which is obsolete in MOT
-#define MOT_OBSOLETE_CODE 1
-
-#define MOT_HAVE_CXX_TEMPLATE_ALIAS 1
-#define MOT_HAVE_INT64_T_IS_LONG 1
-#define MOT_HAVE_SIZE_T_IS_UNSIGNED_LONG 1
-#define MOT_HAVE_STD_HASH 1
-#define MOT_HAVE_STD_IS_TRIVIALLY_COPYABLE 1
-#define MOT_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1
-#define MOT_HAVE_SUPERPAGE 1
-#define MOT_HAVE_TYPE_TRAITS 1
-#define MOT_HAVE_UNALIGNED_ACCESS 0
-#define MOT_HAVE___BUILTIN_CLZ 1
-#define MOT_HAVE___BUILTIN_CLZL 1
-#define MOT_HAVE___BUILTIN_CLZLL 1
-#define MOT_HAVE___BUILTIN_CTZ 1
-#define MOT_HAVE___BUILTIN_CTZL 1
-#define MOT_HAVE___BUILTIN_CTZLL 1
-#define MOT_HAVE___HAS_TRIVIAL_COPY 1
-#define MOT_HAVE___HAS_TRIVIAL_DESTRUCTOR 1
-#define MOT_HAVE___SYNC_BOOL_COMPARE_AND_SWAP 1
-#define MOT_HAVE___SYNC_BOOL_COMPARE_AND_SWAP_8 1
-#define MOT_HAVE___SYNC_FETCH_AND_ADD 1
-#define MOT_HAVE___SYNC_FETCH_AND_ADD_8 1
-#define MOT_HAVE___SYNC_FETCH_AND_OR 1
-#define MOT_HAVE___SYNC_FETCH_AND_OR_8 1
-#define MOT_HAVE___SYNC_VAL_COMPARE_AND_SWAP 1
-#define MOT_HAVE___SYNC_VAL_COMPARE_AND_SWAP_8 1
-
-/* Maximum key length */
-#define MOT_MASSTREE_MAXKEYLEN MAX_KEY_SIZE
-#define MOT_SIZEOF_INT 4
-#define MOT_SIZEOF_LONG 8
-#define MOT_SIZEOF_LONG_LONG 8
-#define MOT_SIZEOF_SHORT 2
-#define MOT_WORDS_BIGENDIAN_SET 1
-/*
-#define masstree_invariant(x, ...) \
- do { \
- } while (0)
-
-#define masstree_precondition(x, ...) \
- do { \
- } while (0)
-*/
-
-#define masstree_invariant(x, ...) assert(x)
-#define masstree_precondition(x, ...) assert(x)
-
-
-
-#ifndef invariant
-#define invariant masstree_invariant
-#endif
-#ifndef precondition
-#define precondition masstree_precondition
-#endif
-
-#ifndef CACHE_LINE_SIZE
-#define CACHE_LINE_SIZE 64
-#endif
-
-#ifndef PRIu64
-#if HAVE_SIZE_T_IS_UNSIGNED_LONG_LONG
-#define PRIu64 "llu"
-#else
-#define PRIu64 "lu"
-#endif
-#endif
-
-
-#endif // MOT_MASSTREE_CONFIG_HPP
--
1.8.3.1

View File

@ -1,153 +0,0 @@
From a702402ec8849b6787bc4da51b785d1dbb0556b8 Mon Sep 17 00:00:00 2001
From: Vinoth Veeraraghavan <vinoth.veeraraghavan@hotmail.com>
Date: Wed, 4 Jan 2023 10:14:23 +0800
Subject: [PATCH] Optimization in split flow
---
kvthread.hh | 6 ++++--
masstree_split.hh | 54 +++++++++++++++++++++--------------------------
2 files changed, 28 insertions(+), 32 deletions(-)
diff --git a/kvthread.hh b/kvthread.hh
index 01d6919..63df4c4 100644
--- a/kvthread.hh
+++ b/kvthread.hh
@@ -28,6 +28,7 @@
enum {
MT_MERR_OK = 0,
+ // Errors that will cause operation failure. bad flows are handled
MT_MERR_MAKE_SPLIT_PRE_ALLOC = 1,
MT_MERR_MAKE_SPLIT_LEAF_ALLOC = 2,
MT_MERR_MAKE_NEW_LAYER_LEAF_ALLOC_1 = 3,
@@ -43,6 +44,8 @@ enum {
// Errors that are being handled internally (Operation should succeed even if last error contains them)
MT_MERR_NON_DISRUPTIVE_ERRORS = 15,
+ MT_MERR_MAKE_INTERNODE_USE_RESERVED = 16,
+ MT_MERR_MAKE_INTERNODE_USE_RESERVED_2 = 17,
// We should not reach the following errors as they should be covered with other errors in more upper layer
MT_MERR_NOT_RETURNED_TO_USER_ERRORS = 20,
@@ -59,7 +62,6 @@ enum {
MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED,
MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED_2,
MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED,
- MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED_2,
MT_MERR_NOT_IN_USE_LAST_ENTRY = 40
};
@@ -84,7 +86,7 @@ extern volatile mrcu_epoch_type active_epoch;
#define MAX_MEMTAG_MASSTREE_LIMBO_GROUP_ALLOCATION_SIZE sizeof(mt_limbo_group)
// Upper bound for the ksuffixes structure max size.
-#define MAX_MEMTAG_MASSTREE_KSUFFIXES_ALLOCATION_SIZE(width) iceil_log2(leaf<P>::external_ksuf_type::safe_size(width, MAX_KEY_SIZE * width));
+#define MAX_MEMTAG_MASSTREE_KSUFFIXES_ALLOCATION_SIZE(width) iceil_log2(leaf<P>::external_ksuf_type::safe_size(width, MASSTREE_MAXKEYLEN * width));
inline uint64_t ng_getGlobalEpoch() {
return globalepoch;
diff --git a/masstree_split.hh b/masstree_split.hh
index 2d53de6..a477757 100644
--- a/masstree_split.hh
+++ b/masstree_split.hh
@@ -199,7 +199,6 @@ bool tcursor<P>::make_split(threadinfo& ti)
// the ikey_bound). But in the latter case, perhaps we can rearrange the
// permutation to do an insert instead.
- //IDAN: LEARN: as we might fail in case the last available slot is 0, why not replace the condition to (n_->size() < n_->width -1) ?
if (n_->size() < n_->width) {
permuter_type perm(n_->permutation_);
perm.exchange(perm.size(), n_->width - 1);
@@ -217,21 +216,7 @@ bool tcursor<P>::make_split(threadinfo& ti)
bool rc = true;
- // 2 optimizations that can reduce the number of internodes allocations:
- // 1. In n_ does not have parent, only 1 internode is required (rare case - only on first split)
- // 2. In case n_'s parent has extra place, and it's height is 1, we dont need internodes at all (common case, but requires early lock of n_'s parent)
- node_type* l_root = n_;
-
- while (!l_root->is_root()) {
- if (n_ != l_root) {
- l_root->stable_annotated(ti.stable_fence());
- }
- l_root = l_root->maybe_parent();
- }
-
- // l_root->height_ is the layer real height or higher.
- uint32_t layer_height = l_root->isleaf() ? 1 : ((internode_type *)l_root)->height_;
- int reserved_nodes = layer_height + 5; // add 5 extra nodes (extra 5 layers in single b-tree)
+ int reserved_nodes = 2;
internode_type * preallocated_internodes[reserved_nodes + 1] = { 0 };
int cur_cache_index = 0;
@@ -274,27 +259,35 @@ bool tcursor<P>::make_split(threadinfo& ti)
while (true) {
masstree_invariant(!n->concurrent || (n->locked() && child->locked() && (n->isleaf() || n->splitting())));
internode_type *next_child = 0;
-
internode_type *p = n->locked_parent(ti);
+ if (cur_cache_index == reserved_nodes) {
+ // Should never happen with pre-allocated internodes (we should have enough reserved nodes). bad flow is not handled
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED);
+ }
+
int kp = -1;
if (n->parent_exists(p)) {
kp = internode_type::bound_type::upper(xikey[sense], *p);
p->mark_insert();
}
- if (kp < 0 || p->height_ > height + 1) {
+ // If cur_cache_index == 1, reserved internode was used on last loop due to memory allocation failure.
+ // In this case, we have only 1 reserved internode left, so stop climbing and add the new internode in the current layer
+ if (kp < 0 || p->height_ > height + 1 || cur_cache_index == 1) {
masstree_invariant(preallocated_internodes[cur_cache_index]);
- internode_type *nn = internode_type::make(height + 1, ti, preallocated_internodes[cur_cache_index++]);
+ internode_type *nn = internode_type::make(height + 1, ti, nullptr);
if (!nn) {
- // Should never happen with pre-allocated internodes. bad flow is not handled
- ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED);
+ ti.set_last_error(MT_MERR_MAKE_INTERNODE_USE_RESERVED);
+ nn = internode_type::make(height + 1, ti, preallocated_internodes[cur_cache_index++]);
}
- if (cur_cache_index == reserved_nodes) {
- // Should never happen with pre-allocated internodes (we should have enough reserved nodes). bad flow is not handled
- ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED);
+ if (!nn) {
+ // Should never happen with pre-allocated internodes. bad flow is not handled
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED);
+ masstree_invariant(false);
}
+
nn->child_[0] = n;
nn->assign(0, xikey[sense], child);
nn->nkeys_ = 1;
@@ -309,15 +302,16 @@ bool tcursor<P>::make_split(threadinfo& ti)
} else {
if (p->size() >= p->width) {
masstree_invariant(preallocated_internodes[cur_cache_index]);
- next_child = internode_type::make(height + 1, ti, preallocated_internodes[cur_cache_index++]);
+ next_child = internode_type::make(height + 1, ti, nullptr);
if (!next_child) {
- // Should never happen with pre-allocated internodes. bad flow is not handled
- ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED_2);
+ ti.set_last_error(MT_MERR_MAKE_INTERNODE_USE_RESERVED_2);
+ next_child = internode_type::make(height + 1, ti, preallocated_internodes[cur_cache_index++]);
}
- if (cur_cache_index == reserved_nodes) {
- // Should never happen with pre-allocated internodes (we should have enough reserved nodes). bad flow is not handled
- ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_EMPTY_PRE_ALLOC_NOT_EXPECTED_2);
+ if (!next_child) {
+ // Should never happen with pre-allocated internodes. bad flow is not handled
+ ti.set_last_error(MT_MERR_MAKE_SPLIT_INTERNODE_ALLOC_NOT_EXPECTED_2);
+ masstree_invariant(false);
}
next_child->assign_version(*p);
--
2.17.1

View File

@ -1,18 +1,18 @@
#!/bin/bash
# Copyright (c) Huawei Technologies Co., Ltd. 2010-2018. All rights reserved.
# Copyright (c) Huawei Technologies Co., Ltd. 2010-2023. All rights reserved.
# description: the script that make install masstree
# date: 2020-12-16
# version: 1.0
# history:
# 2020-12-16 first version
# 2023-08-29 change Masstree base version to v1.0.1 and squash all changes into single patch file
set -e
# change compress type
CUR_DIR=$(pwd)
MASSTREE_PACKAGE=masstree-beta-0.9.0.tar.gz
MASSTREE_PATCH=0001-masstree.patch
MASSTREE_PACKAGE=masstree-beta-1.0.1.tar.gz
MASSTREE_SOURCES_TMP_DIR=tmp
LOCAL_DIR=$(dirname "${LOCAL_PATH}")
MASSTREE_MEGRED_SOURCES_DIR=masstree-beta
@ -24,10 +24,7 @@ mkdir ${MASSTREE_MEGRED_SOURCES_DIR}
tar -zxf $MASSTREE_PACKAGE -C $MASSTREE_MEGRED_SOURCES_DIR --strip-components 1
cd $MASSTREE_MEGRED_SOURCES_DIR
patch -p1 < ../$MASSTREE_PATCH
patch -p1 < ../0002-masstree_oom_fix.patch
patch -p1 < ../0003-masstree_code_cleanup.patch
patch -p1 < ../0004-masstree_reserved_nodes_fix.patch
patch -p1 < ../0001-Masstree-v1.0.1-MOT.patch
sed -i "s/LDFLAGS =/LDFLAGS = -fstack-protector-all -z,now/g" Makefile
sed -i "s/\$(CXX) -shared/\$(CXX) -fstack-protector-all -Wl,-z,relro,-z,now -shared/g" Makefile
@ -41,4 +38,4 @@ mkdir -p ${INSTALL_DIR}/comm/include
mkdir -p ${INSTALL_DIR}/comm/lib
cp ${MASSTREE_MEGRED_SOURCES_DIR}/*.h* ${INSTALL_DIR}/comm/include
cp ${MASSTREE_MEGRED_SOURCES_DIR}/libmasstree.so ${INSTALL_DIR}/comm/lib
rm -rf ${MASSTREE_MEGRED_SOURCES_DIR}

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -2,4 +2,4 @@
1. Usage
sh build.sh to fetch masstree-beta-0.9.0
sh build.sh to fetch masstree-beta-1.0.1

View File

@ -0,0 +1,909 @@
diff -Naur a/cmakeconfig.h.in b/cmakeconfig.h.in
--- a/cmakeconfig.h.in 2023-10-23 14:41:48.150948332 +0800
+++ b/cmakeconfig.h.in 2023-10-23 16:50:33.896373326 +0800
@@ -31,9 +31,15 @@
/* Define to 1 if you have the `accept4` function. */
#cmakedefine HAVE_ACCEPT4 1
+/* Define to 1 if you have the `clock_gettime` function. */
+#cmakedefine HAVE_CLOCK_GETTIME 1
+
/* Define to 1 if you have the `mkostemp` function. */
#cmakedefine HAVE_MKOSTEMP 1
+/* Define to 1 if you have the `GetTickCount64` function. */
+#cmakedefine HAVE_GETTICKCOUNT64 1
+
/* Define to 1 if you have the `initgroups` function. */
#cmakedefine01 HAVE_DECL_INITGROUPS
@@ -70,6 +76,9 @@
/* Define to 1 if you have the <sys/time.h> header file. */
#cmakedefine HAVE_SYS_TIME_H 1
+/* Define to 1 if you have the <sysinfoapi.h> header file. */
+#cmakedefine HAVE_SYSINFOAPI_H 1
+
/* Define to 1 if you have the <syslog.h> header file. */
#cmakedefine HAVE_SYSLOG_H 1
diff -Naur a/CMakeLists.txt b/CMakeLists.txt
--- a/CMakeLists.txt 2023-10-23 14:41:48.154948378 +0800
+++ b/CMakeLists.txt 2023-10-23 17:12:37.595875120 +0800
@@ -260,6 +260,7 @@
check_include_file("pwd.h" HAVE_PWD_H)
check_include_file("sys/socket.h" HAVE_SYS_SOCKET_H)
check_include_file("sys/time.h" HAVE_SYS_TIME_H)
+check_include_file("sysinfoapi.h" HAVE_SYSINFOAPI_H)
check_include_file("syslog.h" HAVE_SYSLOG_H)
check_include_file("time.h" HAVE_TIME_H)
check_include_file("unistd.h" HAVE_UNISTD_H)
@@ -300,9 +301,13 @@
include(CheckFunctionExists)
check_function_exists(_Exit HAVE__EXIT)
check_function_exists(accept4 HAVE_ACCEPT4)
+check_function_exists(clock_gettime HAVE_CLOCK_GETTIME)
check_function_exists(mkostemp HAVE_MKOSTEMP)
include(CheckSymbolExists)
+check_symbol_exists(GetTickCount64 sysinfoapi.h HAVE_GETTICKCOUNT64)
+
+include(CheckSymbolExists)
# XXX does this correctly detect initgroups (un)availability on cygwin?
check_symbol_exists(initgroups grp.h HAVE_DECL_INITGROUPS)
if(NOT HAVE_DECL_INITGROUPS AND HAVE_UNISTD_H)
diff -Naur a/configure.ac b/configure.ac
--- a/configure.ac 2023-10-23 14:41:48.154948378 +0800
+++ b/configure.ac 2023-10-23 16:50:33.900373373 +0800
@@ -607,6 +607,7 @@
string.h \
sys/socket.h \
sys/time.h \
+ sysinfoapi.h \
syslog.h \
time.h \
unistd.h \
@@ -681,6 +682,7 @@
AC_CHECK_FUNCS([ \
_Exit \
accept4 \
+ clock_gettime \
dup2 \
getcwd \
getpwnam \
@@ -706,6 +708,25 @@
AC_CHECK_FUNC([timerfd_create],
[have_timerfd_create=yes], [have_timerfd_create=no])
+AC_MSG_CHECKING([checking for GetTickCount64])
+AC_LINK_IFELSE([AC_LANG_PROGRAM(
+[[
+#include <sysinfoapi.h>
+]],
+[[
+GetTickCount64();
+]])],
+[have_gettickcount64=yes],
+[have_gettickcount64=no])
+
+if test "x${have_gettickcount64}" = "xyes"; then
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_GETTICKCOUNT64], [1],
+ [Define to 1 if you have `GetTickCount64` function.])
+else
+ AC_MSG_RESULT([no])
+fi
+
# For cygwin: we can link initgroups, so AC_CHECK_FUNCS succeeds, but
# cygwin disables initgroups due to feature test macro magic with our
# configuration. FreeBSD declares initgroups() in unistd.h.
diff -Naur a/doc/Makefile.am b/doc/Makefile.am
--- a/doc/Makefile.am 2023-10-23 14:41:48.162948470 +0800
+++ b/doc/Makefile.am 2023-10-23 16:50:33.900373373 +0800
@@ -70,6 +70,7 @@
nghttp2_option_set_user_recv_extension_type.rst \
nghttp2_option_set_max_outbound_ack.rst \
nghttp2_option_set_max_settings.rst \
+ nghttp2_option_set_stream_reset_rate_limit.rst \
nghttp2_pack_settings_payload.rst \
nghttp2_priority_spec_check_default.rst \
nghttp2_priority_spec_default_init.rst \
diff -Naur a/lib/CMakeLists.txt b/lib/CMakeLists.txt
--- a/lib/CMakeLists.txt 2023-10-23 14:41:48.230949253 +0800
+++ b/lib/CMakeLists.txt 2023-10-23 16:50:33.908373466 +0800
@@ -23,6 +23,8 @@
nghttp2_mem.c
nghttp2_http.c
nghttp2_rcbuf.c
+ nghttp2_ratelim.c
+ nghttp2_time.c
nghttp2_debug.c
nghttp2_ksl.c
)
diff -Naur a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h
--- a/lib/includes/nghttp2/nghttp2.h 2023-10-23 14:41:48.230949253 +0800
+++ b/lib/includes/nghttp2/nghttp2.h 2023-10-23 16:50:33.908373466 +0800
@@ -2722,6 +2722,23 @@
/**
* @function
*
+ * This function sets the rate limit for the incoming stream reset
+ * (RST_STREAM frame). It is server use only. It is a token-bucket
+ * based rate limiter. |burst| specifies the number of tokens that is
+ * initially available. The maximum number of tokens is capped to
+ * this value. |rate| specifies the number of tokens that are
+ * regenerated per second. An incoming RST_STREAM consumes one token.
+ * If there is no token available, GOAWAY is sent to tear down the
+ * connection. |burst| and |rate| default to 1000 and 33
+ * respectively.
+ */
+NGHTTP2_EXTERN void
+nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
+ uint64_t burst, uint64_t rate);
+
+/**
+ * @function
+ *
* Initializes |*session_ptr| for client use. The all members of
* |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr|
* does not store |callbacks|. The |user_data| is an arbitrary user
diff -Naur a/lib/Makefile.am b/lib/Makefile.am
--- a/lib/Makefile.am 2023-10-23 14:41:48.230949253 +0800
+++ b/lib/Makefile.am 2023-10-23 16:50:33.908373466 +0800
@@ -49,6 +49,8 @@
nghttp2_mem.c \
nghttp2_http.c \
nghttp2_rcbuf.c \
+ nghttp2_ratelim.c \
+ nghttp2_time.c \
nghttp2_debug.c \
nghttp2_ksl.c
@@ -66,6 +68,8 @@
nghttp2_mem.h \
nghttp2_http.h \
nghttp2_rcbuf.h \
+ nghttp2_ratelim.h \
+ nghttp2_time.h \
nghttp2_debug.h \
nghttp2_ksl.h
diff -Naur a/lib/nghttp2_option.c b/lib/nghttp2_option.c
--- a/lib/nghttp2_option.c 2023-10-23 14:41:48.230949253 +0800
+++ b/lib/nghttp2_option.c 2023-10-23 16:50:33.908373466 +0800
@@ -126,3 +126,10 @@
option->opt_set_mask |= NGHTTP2_OPT_MAX_SETTINGS;
option->max_settings = val;
}
+
+void nghttp2_option_set_stream_reset_rate_limit(nghttp2_option *option,
+ uint64_t burst, uint64_t rate) {
+ option->opt_set_mask |= NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT;
+ option->stream_reset_burst = burst;
+ option->stream_reset_rate = rate;
+}
diff -Naur a/lib/nghttp2_option.h b/lib/nghttp2_option.h
--- a/lib/nghttp2_option.h 2023-10-23 14:41:48.230949253 +0800
+++ b/lib/nghttp2_option.h 2023-10-23 16:50:33.908373466 +0800
@@ -68,6 +68,7 @@
NGHTTP2_OPT_NO_CLOSED_STREAMS = 1 << 10,
NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
+ NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
} nghttp2_option_flag;
/**
@@ -75,6 +76,11 @@
*/
struct nghttp2_option {
/**
+ * NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT
+ */
+ uint64_t stream_reset_burst;
+ uint64_t stream_reset_rate;
+ /**
* NGHTTP2_OPT_MAX_SEND_HEADER_BLOCK_LENGTH
*/
size_t max_send_header_block_length;
diff -Naur a/lib/nghttp2_ratelim.c b/lib/nghttp2_ratelim.c
--- a/lib/nghttp2_ratelim.c 1970-01-01 08:00:00.000000000 +0800
+++ b/lib/nghttp2_ratelim.c 2023-10-23 16:50:33.908373466 +0800
@@ -0,0 +1,75 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_ratelim.h"
+#include "nghttp2_helper.h"
+
+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate) {
+ rl->val = rl->burst = burst;
+ rl->rate = rate;
+ rl->tstamp = 0;
+}
+
+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp) {
+ uint64_t d, gain;
+
+ if (tstamp == rl->tstamp) {
+ return;
+ }
+
+ if (tstamp > rl->tstamp) {
+ d = tstamp - rl->tstamp;
+ } else {
+ d = 1;
+ }
+
+ rl->tstamp = tstamp;
+
+ if (UINT64_MAX / d < rl->rate) {
+ rl->val = rl->burst;
+
+ return;
+ }
+
+ gain = rl->rate * d;
+
+ if (UINT64_MAX - gain < rl->val) {
+ rl->val = rl->burst;
+
+ return;
+ }
+
+ rl->val += gain;
+ rl->val = nghttp2_min(rl->val, rl->burst);
+}
+
+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n) {
+ if (rl->val < n) {
+ return -1;
+ }
+
+ rl->val -= n;
+
+ return 0;
+}
diff -Naur a/lib/nghttp2_ratelim.h b/lib/nghttp2_ratelim.h
--- a/lib/nghttp2_ratelim.h 1970-01-01 08:00:00.000000000 +0800
+++ b/lib/nghttp2_ratelim.h 2023-10-23 16:50:33.908373466 +0800
@@ -0,0 +1,57 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_RATELIM_H
+#define NGHTTP2_RATELIM_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+typedef struct nghttp2_ratelim {
+ /* burst is the maximum value of val. */
+ uint64_t burst;
+ /* rate is the amount of value that is regenerated per 1 tstamp. */
+ uint64_t rate;
+ /* val is the amount of value available to drain. */
+ uint64_t val;
+ /* tstamp is the last timestamp in second resolution that is known
+ to this object. */
+ uint64_t tstamp;
+} nghttp2_ratelim;
+
+/* nghttp2_ratelim_init initializes |rl| with the given parameters. */
+void nghttp2_ratelim_init(nghttp2_ratelim *rl, uint64_t burst, uint64_t rate);
+
+/* nghttp2_ratelim_update updates rl->val with the current |tstamp|
+ given in second resolution. */
+void nghttp2_ratelim_update(nghttp2_ratelim *rl, uint64_t tstamp);
+
+/* nghttp2_ratelim_drain drains |n| from rl->val. It returns 0 if it
+ succeeds, or -1. */
+int nghttp2_ratelim_drain(nghttp2_ratelim *rl, uint64_t n);
+
+#endif /* NGHTTP2_RATELIM_H */
diff -Naur a/lib/nghttp2_session.c b/lib/nghttp2_session.c
--- a/lib/nghttp2_session.c 2023-10-23 14:41:48.230949253 +0800
+++ b/lib/nghttp2_session.c 2023-10-23 16:50:33.908373466 +0800
@@ -36,6 +36,7 @@
#include "nghttp2_option.h"
#include "nghttp2_http.h"
#include "nghttp2_pq.h"
+#include "nghttp2_time.h"
#include "nghttp2_debug.h"
/*
@@ -443,6 +444,10 @@
NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS;
(*session_ptr)->pending_enable_push = 1;
+ nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim,
+ NGHTTP2_DEFAULT_STREAM_RESET_BURST,
+ NGHTTP2_DEFAULT_STREAM_RESET_RATE);
+
if (server) {
(*session_ptr)->server = 1;
}
@@ -527,6 +532,12 @@
option->max_settings) {
(*session_ptr)->max_settings = option->max_settings;
}
+
+ if (option->opt_set_mask & NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT) {
+ nghttp2_ratelim_init(&(*session_ptr)->stream_reset_ratelim,
+ option->stream_reset_burst,
+ option->stream_reset_rate);
+ }
}
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
@@ -4154,6 +4165,23 @@
return nghttp2_session_on_priority_received(session, frame);
}
+static int session_update_stream_reset_ratelim(nghttp2_session *session) {
+ if (!session->server || (session->goaway_flags & NGHTTP2_GOAWAY_SUBMITTED)) {
+ return 0;
+ }
+
+ nghttp2_ratelim_update(&session->stream_reset_ratelim,
+ nghttp2_time_now_sec());
+
+ if (nghttp2_ratelim_drain(&session->stream_reset_ratelim, 1) == 0) {
+ return 0;
+ }
+
+ return nghttp2_session_add_goaway(session, session->last_recv_stream_id,
+ NGHTTP2_INTERNAL_ERROR, NULL, 0,
+ NGHTTP2_GOAWAY_AUX_NONE);
+}
+
int nghttp2_session_on_rst_stream_received(nghttp2_session *session,
nghttp2_frame *frame) {
int rv;
@@ -4183,7 +4211,8 @@
if (nghttp2_is_fatal(rv)) {
return rv;
}
- return 0;
+
+ return session_update_stream_reset_ratelim(session);
}
static int session_process_rst_stream_frame(nghttp2_session *session) {
@@ -6964,6 +6993,9 @@
nghttp2_mem_free(mem, item);
return rv;
}
+
+ session->goaway_flags |= NGHTTP2_GOAWAY_SUBMITTED;
+
return 0;
}
diff -Naur a/lib/nghttp2_session.h b/lib/nghttp2_session.h
--- a/lib/nghttp2_session.h 2023-10-23 14:41:48.230949253 +0800
+++ b/lib/nghttp2_session.h 2023-10-23 16:50:33.908373466 +0800
@@ -39,6 +39,7 @@
#include "nghttp2_buf.h"
#include "nghttp2_callbacks.h"
#include "nghttp2_mem.h"
+#include "nghttp2_ratelim.h"
/* The global variable for tests where we want to disable strict
preface handling. */
@@ -102,6 +103,10 @@
/* The default value of maximum number of concurrent streams. */
#define NGHTTP2_DEFAULT_MAX_CONCURRENT_STREAMS 0xffffffffu
+/* The default values for stream reset rate limiter. */
+#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
+#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
+
/* Internal state when receiving incoming frame */
typedef enum {
/* Receiving frame header */
@@ -176,7 +181,9 @@
/* Flag means GOAWAY was sent */
NGHTTP2_GOAWAY_SENT = 0x4,
/* Flag means GOAWAY was received */
- NGHTTP2_GOAWAY_RECV = 0x8
+ NGHTTP2_GOAWAY_RECV = 0x8,
+ /* Flag means GOAWAY has been submitted at least once */
+ NGHTTP2_GOAWAY_SUBMITTED = 0x10
} nghttp2_goaway_flag;
/* nghttp2_inflight_settings stores the SETTINGS entries which local
@@ -227,6 +234,9 @@
/* Queue of In-flight SETTINGS values. SETTINGS bearing ACK is not
considered as in-flight. */
nghttp2_inflight_settings *inflight_settings_head;
+ /* Stream reset rate limiter. If receiving excessive amount of
+ stream resets, GOAWAY will be sent. */
+ nghttp2_ratelim stream_reset_ratelim;
/* The number of outgoing streams. This will be capped by
remote_settings.max_concurrent_streams. */
size_t num_outgoing_streams;
diff -Naur a/lib/nghttp2_time.c b/lib/nghttp2_time.c
--- a/lib/nghttp2_time.c 1970-01-01 08:00:00.000000000 +0800
+++ b/lib/nghttp2_time.c 2023-10-23 16:50:33.908373466 +0800
@@ -0,0 +1,62 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_time.h"
+
+#ifdef HAVE_TIME_H
+# include <time.h>
+#endif /* HAVE_TIME_H */
+
+#ifdef HAVE_SYSINFOAPI_H
+# include <sysinfoapi.h>
+#endif /* HAVE_SYSINFOAPI_H */
+
+#ifndef HAVE_GETTICKCOUNT64
+static uint64_t time_now_sec(void) {
+ time_t t = time(NULL);
+
+ if (t == -1) {
+ return 0;
+ }
+
+ return (uint64_t)t;
+}
+#endif /* HAVE_GETTICKCOUNT64 */
+
+#ifdef HAVE_CLOCK_GETTIME
+uint64_t nghttp2_time_now_sec(void) {
+ struct timespec tp;
+ int rv = clock_gettime(CLOCK_MONOTONIC, &tp);
+
+ if (rv == -1) {
+ return time_now_sec();
+ }
+
+ return (uint64_t)tp.tv_sec;
+}
+#elif defined(HAVE_GETTICKCOUNT64)
+uint64_t nghttp2_time_now_sec(void) { return GetTickCount64() / 1000; }
+#else /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */
+uint64_t nghttp2_time_now_sec(void) { return time_now_sec(); }
+#endif /* !HAVE_CLOCK_GETTIME && !HAVE_GETTICKCOUNT64 */
diff -Naur a/lib/nghttp2_time.h b/lib/nghttp2_time.h
--- a/lib/nghttp2_time.h 1970-01-01 08:00:00.000000000 +0800
+++ b/lib/nghttp2_time.h 2023-10-23 16:50:33.908373466 +0800
@@ -0,0 +1,38 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_TIME_H
+#define NGHTTP2_TIME_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+#include <nghttp2/nghttp2.h>
+
+/* nghttp2_time_now_sec returns seconds from implementation-specific
+ timepoint. If it is unable to get seconds, it returns 0. */
+uint64_t nghttp2_time_now_sec(void);
+
+#endif /* NGHTTP2_TIME_H */
diff -Naur a/tests/CMakeLists.txt b/tests/CMakeLists.txt
--- a/tests/CMakeLists.txt 2023-10-23 14:41:48.238949345 +0800
+++ b/tests/CMakeLists.txt 2023-10-23 16:50:33.916373560 +0800
@@ -21,6 +21,7 @@
nghttp2_npn_test.c
nghttp2_helper_test.c
nghttp2_buf_test.c
+ nghttp2_ratelim_test.c
)
add_executable(main EXCLUDE_FROM_ALL
diff -Naur a/tests/main.c b/tests/main.c
--- a/tests/main.c 2023-10-23 14:41:48.238949345 +0800
+++ b/tests/main.c 2023-10-23 16:50:33.916373560 +0800
@@ -40,6 +40,7 @@
#include "nghttp2_npn_test.h"
#include "nghttp2_helper_test.h"
#include "nghttp2_buf_test.h"
+#include "nghttp2_ratelim_test.h"
extern int nghttp2_enable_strict_preface;
@@ -329,6 +330,8 @@
test_nghttp2_session_no_closed_streams) ||
!CU_add_test(pSuite, "session_set_stream_user_data",
test_nghttp2_session_set_stream_user_data) ||
+ !CU_add_test(pSuite, "session_stream_reset_ratelim",
+ test_nghttp2_session_stream_reset_ratelim) ||
!CU_add_test(pSuite, "http_mandatory_headers",
test_nghttp2_http_mandatory_headers) ||
!CU_add_test(pSuite, "http_content_length",
@@ -425,7 +428,9 @@
!CU_add_test(pSuite, "bufs_advance", test_nghttp2_bufs_advance) ||
!CU_add_test(pSuite, "bufs_next_present",
test_nghttp2_bufs_next_present) ||
- !CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc)) {
+ !CU_add_test(pSuite, "bufs_realloc", test_nghttp2_bufs_realloc))
+ !CU_add_test(pSuite, "ratelim_update", test_nghttp2_ratelim_update) ||
+ !CU_add_test(pSuite, "ratelim_drain", test_nghttp2_ratelim_drain)) {
CU_cleanup_registry();
return (int)CU_get_error();
}
diff -Naur a/tests/Makefile.am b/tests/Makefile.am
--- a/tests/Makefile.am 2023-10-23 14:41:48.238949345 +0800
+++ b/tests/Makefile.am 2023-10-23 16:50:33.916373560 +0800
@@ -40,14 +40,16 @@
nghttp2_hd_test.c \
nghttp2_npn_test.c \
nghttp2_helper_test.c \
- nghttp2_buf_test.c
+ nghttp2_buf_test.c \
+ nghttp2_ratelim_test.c
HFILES = nghttp2_pq_test.h nghttp2_map_test.h nghttp2_queue_test.h \
nghttp2_session_test.h \
nghttp2_frame_test.h nghttp2_stream_test.h nghttp2_hd_test.h \
nghttp2_npn_test.h nghttp2_helper_test.h \
nghttp2_test_helper.h \
- nghttp2_buf_test.h
+ nghttp2_buf_test.h \
+ nghttp2_ratelim_test.c
main_SOURCES = $(HFILES) $(OBJECTS)
diff -Naur a/tests/nghttp2_ratelim_test.c b/tests/nghttp2_ratelim_test.c
--- a/tests/nghttp2_ratelim_test.c 1970-01-01 08:00:00.000000000 +0800
+++ b/tests/nghttp2_ratelim_test.c 2023-10-23 16:50:33.916373560 +0800
@@ -0,0 +1,101 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#include "nghttp2_ratelim_test.h"
+
+#include <stdio.h>
+
+#include <CUnit/CUnit.h>
+
+#include "nghttp2_ratelim.h"
+
+void test_nghttp2_ratelim_update(void) {
+ nghttp2_ratelim rl;
+
+ nghttp2_ratelim_init(&rl, 1000, 21);
+
+ CU_ASSERT(1000 == rl.val);
+ CU_ASSERT(1000 == rl.burst);
+ CU_ASSERT(21 == rl.rate);
+ CU_ASSERT(0 == rl.tstamp);
+
+ nghttp2_ratelim_update(&rl, 999);
+
+ CU_ASSERT(1000 == rl.val);
+ CU_ASSERT(999 == rl.tstamp);
+
+ nghttp2_ratelim_drain(&rl, 100);
+
+ CU_ASSERT(900 == rl.val);
+
+ nghttp2_ratelim_update(&rl, 1000);
+
+ CU_ASSERT(921 == rl.val);
+
+ nghttp2_ratelim_update(&rl, 1002);
+
+ CU_ASSERT(963 == rl.val);
+
+ nghttp2_ratelim_update(&rl, 1004);
+
+ CU_ASSERT(1000 == rl.val);
+ CU_ASSERT(1004 == rl.tstamp);
+
+ /* timer skew */
+ nghttp2_ratelim_init(&rl, 1000, 21);
+ nghttp2_ratelim_update(&rl, 1);
+
+ CU_ASSERT(1000 == rl.val);
+
+ nghttp2_ratelim_update(&rl, 0);
+
+ CU_ASSERT(1000 == rl.val);
+
+ /* rate * duration overflow */
+ nghttp2_ratelim_init(&rl, 1000, 100);
+ nghttp2_ratelim_drain(&rl, 999);
+
+ CU_ASSERT(1 == rl.val);
+
+ nghttp2_ratelim_update(&rl, UINT64_MAX);
+
+ CU_ASSERT(1000 == rl.val);
+
+ /* val + rate * duration overflow */
+ nghttp2_ratelim_init(&rl, UINT64_MAX - 1, 2);
+ nghttp2_ratelim_update(&rl, 1);
+
+ CU_ASSERT(UINT64_MAX - 1 == rl.val);
+}
+
+void test_nghttp2_ratelim_drain(void) {
+ nghttp2_ratelim rl;
+
+ nghttp2_ratelim_init(&rl, 100, 7);
+
+ CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 101));
+ CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 51));
+ CU_ASSERT(0 == nghttp2_ratelim_drain(&rl, 49));
+ CU_ASSERT(-1 == nghttp2_ratelim_drain(&rl, 1));
+}
diff -Naur a/tests/nghttp2_ratelim_test.h b/tests/nghttp2_ratelim_test.h
--- a/tests/nghttp2_ratelim_test.h 1970-01-01 08:00:00.000000000 +0800
+++ b/tests/nghttp2_ratelim_test.h 2023-10-23 16:50:33.916373560 +0800
@@ -0,0 +1,35 @@
+/*
+ * nghttp2 - HTTP/2 C Library
+ *
+ * Copyright (c) 2023 nghttp2 contributors
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ */
+#ifndef NGHTTP2_RATELIM_TEST_H
+#define NGHTTP2_RATELIM_TEST_H
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif /* HAVE_CONFIG_H */
+
+void test_nghttp2_ratelim_update(void);
+void test_nghttp2_ratelim_drain(void);
+
+#endif /* NGHTTP2_RATELIM_TEST_H */
diff -Naur a/tests/nghttp2_session_test.c b/tests/nghttp2_session_test.c
--- a/tests/nghttp2_session_test.c 2023-10-23 14:41:48.238949345 +0800
+++ b/tests/nghttp2_session_test.c 2023-10-23 16:50:33.916373560 +0800
@@ -11055,6 +11055,109 @@
nghttp2_session_del(session);
}
+void test_nghttp2_session_stream_reset_ratelim(void) {
+ nghttp2_session *session;
+ nghttp2_session_callbacks callbacks;
+ nghttp2_frame frame;
+ ssize_t rv;
+ nghttp2_bufs bufs;
+ nghttp2_buf *buf;
+ nghttp2_mem *mem;
+ size_t i;
+ nghttp2_hd_deflater deflater;
+ size_t nvlen;
+ nghttp2_nv *nva;
+ int32_t stream_id;
+ nghttp2_outbound_item *item;
+ nghttp2_option *option;
+
+ mem = nghttp2_mem_default();
+ frame_pack_bufs_init(&bufs);
+
+ memset(&callbacks, 0, sizeof(nghttp2_session_callbacks));
+ callbacks.send_callback = null_send_callback;
+
+ nghttp2_option_new(&option);
+ nghttp2_option_set_stream_reset_rate_limit(
+ option, NGHTTP2_DEFAULT_STREAM_RESET_BURST, 0);
+
+ nghttp2_session_server_new2(&session, &callbacks, NULL, option);
+
+ nghttp2_frame_settings_init(&frame.settings, NGHTTP2_FLAG_NONE, NULL, 0);
+ rv = nghttp2_frame_pack_settings(&bufs, &frame.settings);
+
+ CU_ASSERT(0 == rv);
+
+ nghttp2_frame_settings_free(&frame.settings, mem);
+
+ buf = &bufs.head->buf;
+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
+
+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
+
+ /* Send SETTINGS ACK */
+ rv = nghttp2_session_send(session);
+
+ CU_ASSERT(0 == rv);
+
+ nghttp2_hd_deflate_init(&deflater, mem);
+
+ for (i = 0; i < NGHTTP2_DEFAULT_STREAM_RESET_BURST + 2; ++i) {
+ stream_id = (int32_t)(i * 2 + 1);
+
+ nghttp2_bufs_reset(&bufs);
+
+ /* HEADERS */
+ nvlen = ARRLEN(reqnv);
+ nghttp2_nv_array_copy(&nva, reqnv, nvlen, mem);
+ nghttp2_frame_headers_init(&frame.headers, NGHTTP2_FLAG_END_HEADERS,
+ stream_id, NGHTTP2_HCAT_HEADERS, NULL, nva,
+ nvlen);
+ rv = nghttp2_frame_pack_headers(&bufs, &frame.headers, &deflater);
+
+ CU_ASSERT(0 == rv);
+
+ nghttp2_frame_headers_free(&frame.headers, mem);
+
+ buf = &bufs.head->buf;
+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
+
+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
+
+ nghttp2_bufs_reset(&bufs);
+
+ /* RST_STREAM */
+ nghttp2_frame_rst_stream_init(&frame.rst_stream, stream_id,
+ NGHTTP2_NO_ERROR);
+ nghttp2_frame_pack_rst_stream(&bufs, &frame.rst_stream);
+ nghttp2_frame_rst_stream_free(&frame.rst_stream);
+
+ buf = &bufs.head->buf;
+ rv = nghttp2_session_mem_recv(session, buf->pos, nghttp2_buf_len(buf));
+
+ CU_ASSERT((ssize_t)nghttp2_buf_len(buf) == rv);
+
+ if (i < NGHTTP2_DEFAULT_STREAM_RESET_BURST) {
+ CU_ASSERT(0 == nghttp2_outbound_queue_size(&session->ob_reg));
+
+ continue;
+ }
+
+ CU_ASSERT(1 == nghttp2_outbound_queue_size(&session->ob_reg));
+
+ item = nghttp2_session_get_next_ob_item(session);
+
+ CU_ASSERT(NGHTTP2_GOAWAY == item->frame.hd.type);
+ CU_ASSERT(NGHTTP2_DEFAULT_STREAM_RESET_BURST * 2 + 1 ==
+ item->frame.goaway.last_stream_id);
+ }
+
+ nghttp2_hd_deflate_free(&deflater);
+ nghttp2_session_del(session);
+ nghttp2_bufs_free(&bufs);
+ nghttp2_option_del(option);
+}
+
static void check_nghttp2_http_recv_headers_fail(
nghttp2_session *session, nghttp2_hd_deflater *deflater, int32_t stream_id,
int stream_state, const nghttp2_nv *nva, size_t nvlen) {
diff -Naur a/tests/nghttp2_session_test.h b/tests/nghttp2_session_test.h
--- a/tests/nghttp2_session_test.h 2023-10-23 14:41:48.238949345 +0800
+++ b/tests/nghttp2_session_test.h 2023-10-23 16:50:33.916373560 +0800
@@ -162,6 +162,7 @@
void test_nghttp2_session_pause_data(void);
void test_nghttp2_session_no_closed_streams(void);
void test_nghttp2_session_set_stream_user_data(void);
+void test_nghttp2_session_stream_reset_ratelim(void);
void test_nghttp2_http_mandatory_headers(void);
void test_nghttp2_http_content_length(void);
void test_nghttp2_http_content_length_mismatch(void);

View File

@ -0,0 +1,161 @@
diff -Naur a/doc/Makefile.am b/doc/Makefile.am
--- a/doc/Makefile.am 2024-04-15 19:33:38.344785283 +0800
+++ b/doc/Makefile.am 2024-04-15 20:15:35.145757969 +0800
@@ -68,6 +68,7 @@
nghttp2_option_set_no_recv_client_magic.rst \
nghttp2_option_set_peer_max_concurrent_streams.rst \
nghttp2_option_set_user_recv_extension_type.rst \
+ nghttp2_option_set_max_continuations.rst \
nghttp2_option_set_max_outbound_ack.rst \
nghttp2_option_set_max_settings.rst \
nghttp2_option_set_stream_reset_rate_limit.rst \
diff -Naur a/lib/includes/nghttp2/nghttp2.h b/lib/includes/nghttp2/nghttp2.h
--- a/lib/includes/nghttp2/nghttp2.h 2024-04-15 19:33:38.348785336 +0800
+++ b/lib/includes/nghttp2/nghttp2.h 2024-04-15 20:15:35.149758022 +0800
@@ -440,7 +440,12 @@
* exhaustion on server side to send these frames forever and does
* not read network.
*/
- NGHTTP2_ERR_FLOODED = -904
+ NGHTTP2_ERR_FLOODED = -904,
+ /**
+ * When a local endpoint receives too many CONTINUATION frames
+ * following a HEADER frame.
+ */
+ NGHTTP2_ERR_TOO_MANY_CONTINUATIONS = -905,
} nghttp2_error;
/**
@@ -2738,6 +2743,17 @@
/**
* @function
+ *
+ * This function sets the maximum number of CONTINUATION frames
+ * following an incoming HEADER frame. If more than those frames are
+ * received, the remote endpoint is considered to be misbehaving and
+ * session will be closed. The default value is 8.
+ */
+NGHTTP2_EXTERN void nghttp2_option_set_max_continuations(nghttp2_option *option,
+ size_t val);
+
+/**
+ * @function
*
* Initializes |*session_ptr| for client use. The all members of
* |callbacks| are copied to |*session_ptr|. Therefore |*session_ptr|
diff -Naur a/lib/nghttp2_helper.c b/lib/nghttp2_helper.c
--- a/lib/nghttp2_helper.c 2024-04-15 19:33:38.352785388 +0800
+++ b/lib/nghttp2_helper.c 2024-04-15 20:15:35.149758022 +0800
@@ -336,6 +336,8 @@
"closed";
case NGHTTP2_ERR_TOO_MANY_SETTINGS:
return "SETTINGS frame contained more than the maximum allowed entries";
+ case NGHTTP2_ERR_TOO_MANY_CONTINUATIONS:
+ return "Too many CONTINUATION frames following a HEADER frame";
default:
return "Unknown error code";
}
diff -Naur a/lib/nghttp2_option.c b/lib/nghttp2_option.c
--- a/lib/nghttp2_option.c 2024-04-15 19:33:38.348785336 +0800
+++ b/lib/nghttp2_option.c 2024-04-15 20:15:35.149758022 +0800
@@ -133,3 +133,8 @@
option->stream_reset_burst = burst;
option->stream_reset_rate = rate;
}
+
+void nghttp2_option_set_max_continuations(nghttp2_option *option, size_t val) {
+ option->opt_set_mask |= NGHTTP2_OPT_MAX_CONTINUATIONS;
+ option->max_continuations = val;
+}
diff -Naur a/lib/nghttp2_option.h b/lib/nghttp2_option.h
--- a/lib/nghttp2_option.h 2024-04-15 19:33:38.352785388 +0800
+++ b/lib/nghttp2_option.h 2024-04-15 20:15:35.153758074 +0800
@@ -69,6 +69,7 @@
NGHTTP2_OPT_MAX_OUTBOUND_ACK = 1 << 11,
NGHTTP2_OPT_MAX_SETTINGS = 1 << 12,
NGHTTP2_OPT_STREAM_RESET_RATE_LIMIT = 1 << 15,
+ NGHTTP2_OPT_MAX_CONTINUATIONS = 1 << 16,
} nghttp2_option_flag;
/**
@@ -97,6 +98,10 @@
*/
size_t max_settings;
/**
+ * NGHTTP2_OPT_MAX_CONTINUATIONS
+ */
+ size_t max_continuations;
+ /**
* Bitwise OR of nghttp2_option_flag to determine that which fields
* are specified.
*/
diff -Naur a/lib/nghttp2_session.c b/lib/nghttp2_session.c
--- a/lib/nghttp2_session.c 2024-04-15 19:33:38.352785388 +0800
+++ b/lib/nghttp2_session.c 2024-04-15 20:15:35.153758074 +0800
@@ -464,6 +464,7 @@
(*session_ptr)->max_send_header_block_length = NGHTTP2_MAX_HEADERSLEN;
(*session_ptr)->max_outbound_ack = NGHTTP2_DEFAULT_MAX_OBQ_FLOOD_ITEM;
(*session_ptr)->max_settings = NGHTTP2_DEFAULT_MAX_SETTINGS;
+ (*session_ptr)->max_continuations = NGHTTP2_DEFAULT_MAX_CONTINUATIONS;
if (option) {
if ((option->opt_set_mask & NGHTTP2_OPT_NO_AUTO_WINDOW_UPDATE) &&
@@ -538,6 +539,10 @@
option->stream_reset_burst,
option->stream_reset_rate);
}
+
+ if (option->opt_set_mask & NGHTTP2_OPT_MAX_CONTINUATIONS) {
+ (*session_ptr)->max_continuations = option->max_continuations;
+ }
}
rv = nghttp2_hd_deflate_init2(&(*session_ptr)->hd_deflater,
@@ -6310,6 +6315,8 @@
}
}
session_inbound_frame_reset(session);
+
+ session->num_continuations = 0;
}
break;
}
@@ -6430,6 +6437,10 @@
fprintf(stderr, "recv: [IB_IGN_CONTINUATION]\n");
}
#endif /* DEBUGBUILD */
+
+ if (++session->num_continuations > session->max_continuations) {
+ return NGHTTP2_ERR_TOO_MANY_CONTINUATIONS;
+ }
readlen = inbound_frame_buf_read(iframe, in, last);
in += readlen;
diff -Naur a/lib/nghttp2_session.h b/lib/nghttp2_session.h
--- a/lib/nghttp2_session.h 2024-04-15 19:33:38.352785388 +0800
+++ b/lib/nghttp2_session.h 2024-04-15 20:15:35.153758074 +0800
@@ -107,6 +107,10 @@
#define NGHTTP2_DEFAULT_STREAM_RESET_BURST 1000
#define NGHTTP2_DEFAULT_STREAM_RESET_RATE 33
+/* The default max number of CONTINUATION frames following an incoming
+ HEADER frame. */
+#define NGHTTP2_DEFAULT_MAX_CONTINUATIONS 8
+
/* Internal state when receiving incoming frame */
typedef enum {
/* Receiving frame header */
@@ -279,6 +283,12 @@
size_t max_send_header_block_length;
/* The maximum number of settings accepted per SETTINGS frame. */
size_t max_settings;
+ /* The maximum number of CONTINUATION frames following an incoming
+ HEADER frame. */
+ size_t max_continuations;
+ /* The number of CONTINUATION frames following an incoming HEADER
+ frame. This variable is reset when END_HEADERS flag is seen. */
+ size_t num_continuations;
/* Next Stream ID. Made unsigned int to detect >= (1 << 31). */
uint32_t next_stream_id;
/* The last stream ID this session initiated. For client session,

View File

@ -24,7 +24,9 @@ rm -rf install_*
mkdir -p ${build_dir}
cd $nghttp2_dir
patch -p1 < ../cve-2023-35945.patch
patch -p1 < ../CVE-2023-44487.patch
patch -p1 < ../CVE-2024-28182.patch
cmake -DCMAKE_INSTALL_PREFIX=$build_dir -D CMAKE_PROJECT_INCLUDE=${current_dir}/project_include.cmake
make install -sj

View File

@ -0,0 +1,35 @@
diff -Naur a/lib/nghttp2_session.c b/lib/nghttp2_session.c
--- a/lib/nghttp2_session.c 2023-07-25 14:24:37.157709999 +0800
+++ b/lib/nghttp2_session.c 2023-07-25 14:22:35.604257644 +0800
@@ -2938,6 +2938,7 @@
break;
}
if (rv < 0) {
+ int rv2 = 0;
int32_t opened_stream_id = 0;
uint32_t error_code = NGHTTP2_INTERNAL_ERROR;
@@ -2982,19 +2983,19 @@
}
if (opened_stream_id) {
/* careful not to override rv */
- int rv2;
rv2 = nghttp2_session_close_stream(session, opened_stream_id,
error_code);
- if (nghttp2_is_fatal(rv2)) {
- return rv2;
- }
}
nghttp2_outbound_item_free(item, mem);
nghttp2_mem_free(mem, item);
active_outbound_item_reset(aob, mem);
+ if (nghttp2_is_fatal(rv2)) {
+ return rv2;
+ }
+
if (rv == NGHTTP2_ERR_HEADER_COMP) {
/* If header compression error occurred, should terminiate
connection. */

View File

@ -115,6 +115,12 @@ class OPOperator():
patch_cmd = 'cd %s/%s; patch -p1 < ../%s' % (self.local_dir, source_code_path, pre_patch)
ret = self.exe_cmd(patch_cmd)
self.error_handler(ret)
status, output = subprocess.getstatusoutput('uname -m')
self.error_handler(status)
cpu_arch = output
if cpu_arch in ('loongarch64') :
ret = self.exe_cmd('cd %s/%s; cp -rf %s/../../build-aux/* ./build-aux/' % (self.local_dir, source_code_path, self.local_dir))
self.error_handler(ret)
# compile source code type
for c_type in self.compiletype:
if c_type == 'comm':

Binary file not shown.

View File

@ -0,0 +1,108 @@
From 400e9ffc906d66318e4f9364494809d5a519c718 Mon Sep 17 00:00:00 2001
From: Paul Yang <yang.yang@baishancloud.com>
Date: Wed, 13 Mar 2019 17:22:31 +0800
Subject: [PATCH 06/15] Add documents for SM2 cert verification
This follows #8321 which added the SM2 certificate verification feature.
This commit adds the related docs - the newly added 2 APIs and options
in apps/verify.
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8465)
---
doc/man1/verify.pod | 14 ++++++++++++
doc/man3/X509_get0_sm2_id.pod | 43 +++++++++++++++++++++++++++++++++++
2 files changed, 57 insertions(+)
create mode 100644 doc/man3/X509_get0_sm2_id.pod
diff --git a/doc/man1/verify.pod b/doc/man1/verify.pod
index da2b702..a6b6b2b 100644
--- a/doc/man1/verify.pod
+++ b/doc/man1/verify.pod
@@ -50,6 +50,8 @@ B<openssl> B<verify>
[B<-verify_name name>]
[B<-x509_strict>]
[B<-show_chain>]
+[B<-sm2-id string>]
+[B<-sm2-hex-id hex-string>]
[B<->]
[certificates]
@@ -319,6 +321,16 @@ Display information about the certificate chain that has been built (if
successful). Certificates in the chain that came from the untrusted list will be
flagged as "untrusted".
+=item B<-sm2-id>
+
+Specify the ID string to use when verifying an SM2 certificate. The ID string is
+required by the SM2 signature algorithm for signing and verification.
+
+=item B<-sm2-hex-id>
+
+Specify a binary ID string to use when signing or verifying using an SM2
+certificate. The argument for this option is string of hexadecimal digits.
+
=item B<->
Indicates the last option. All arguments following this are assumed to be
@@ -774,6 +786,8 @@ The B<-show_chain> option was added in OpenSSL 1.1.0.
The B<-issuer_checks> option is deprecated as of OpenSSL 1.1.0 and
is silently ignored.
+The B<-sm2-id> and B<-sm2-hex-id> options were added in OpenSSL 3.0.0.
+
=head1 COPYRIGHT
Copyright 2000-2020 The OpenSSL Project Authors. All Rights Reserved.
diff --git a/doc/man3/X509_get0_sm2_id.pod b/doc/man3/X509_get0_sm2_id.pod
new file mode 100644
index 0000000..84da71e
--- /dev/null
+++ b/doc/man3/X509_get0_sm2_id.pod
@@ -0,0 +1,43 @@
+=pod
+
+=head1 NAME
+
+X509_get0_sm2_id, X509_set_sm2_id - get or set SM2 ID for certificate operations
+
+=head1 SYNOPSIS
+
+ #include <openssl/x509.h>
+
+ ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
+ void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
+
+=head1 DESCRIPTION
+
+X509_get0_sm2_id() gets the ID value of an SM2 certificate B<x> by returning an
+B<ASN1_OCTET_STRING> object which should not be freed by the caller.
+X509_set_sm2_id() sets the B<sm2_id> value to an SM2 certificate B<x>.
+
+=head1 NOTES
+
+SM2 signature algorithm requires an ID value when generating and verifying a
+signature. The functions described in this manual provide the user with the
+ability to set and retrieve the SM2 ID value.
+
+=head1 RETURN VALUES
+
+X509_set_sm2_id() does not return a value.
+
+=head1 SEE ALSO
+
+L<X509_verify(3)>, L<SM2(7)>
+
+=head1 COPYRIGHT
+
+Copyright 2019 The OpenSSL Project Authors. All Rights Reserved.
+
+Licensed under the Apache License 2.0 (the "License"). You may not use
+this file except in compliance with the License. You can obtain a copy
+in the file LICENSE in the source distribution or at
+L<https://www.openssl.org/source/license.html>.
+
+=cut
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,127 @@
From c08251384c0405c151a90b315b8f333c38c74eb2 Mon Sep 17 00:00:00 2001
From: Paul Yang <yang.yang@baishancloud.com>
Date: Wed, 13 Mar 2019 16:54:11 +0800
Subject: [PATCH 05/15] Add test cases for SM2 cert verification
This follows #8321 which added the SM2 certificate verification feature.
This commit adds some test cases for #8321.
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8465)
---
test/certs/sm2-ca-cert.pem | 14 +++++++++++++
test/certs/{sm2.crt => sm2.pem} | 0
test/recipes/20-test_pkeyutl.t | 37 +++++++++++++--------------------
test/recipes/25-test_verify.t | 14 ++++++++++++-
4 files changed, 42 insertions(+), 23 deletions(-)
create mode 100644 test/certs/sm2-ca-cert.pem
rename test/certs/{sm2.crt => sm2.pem} (100%)
diff --git a/test/certs/sm2-ca-cert.pem b/test/certs/sm2-ca-cert.pem
new file mode 100644
index 0000000..5677ac6
--- /dev/null
+++ b/test/certs/sm2-ca-cert.pem
@@ -0,0 +1,14 @@
+-----BEGIN CERTIFICATE-----
+MIICJDCCAcqgAwIBAgIJAOlkpDpSrmVbMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT
+AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl
+c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe
+Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMGgxCzAJBgNVBAYTAkNOMQsw
+CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn
+MRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTBZMBMGByqG
+SM49AgEGCCqBHM9VAYItA0IABHRYnqErofBdXPptvvO7+BSVJxcpHuTGnZ+UPrbU
+5kVEUMaUnNOeMJZl/vRGimZCm/AkReJmRfnb15ESHR+ssp6jXTBbMB0GA1UdDgQW
+BBTFjcWu/zJgSZ5SKUlU5Vx4/0W5dDAfBgNVHSMEGDAWgBTFjcWu/zJgSZ5SKUlU
+5Vx4/0W5dDAMBgNVHRMEBTADAQH/MAsGA1UdDwQEAwIBBjAKBggqgRzPVQGDdQNI
+ADBFAiEAs6byi1nSQtFELOw/2tQIv5AEsZFR5MJ/oB2ztXzs2LYCIEfIw4xlUH6X
+YFhs4RnIa0K9Ng1ebsGPrifYkudwBIk3
+-----END CERTIFICATE-----
diff --git a/test/certs/sm2.crt b/test/certs/sm2.pem
similarity index 100%
rename from test/certs/sm2.crt
rename to test/certs/sm2.pem
diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t
index 1457530..a36d41e 100644
--- a/test/recipes/20-test_pkeyutl.t
+++ b/test/recipes/20-test_pkeyutl.t
@@ -17,32 +17,25 @@ setup("test_pkeyutl");
plan tests => 2;
-sub sign
-{
- # Utilize the sm2.crt as the TBS file
- return run(app(([ 'openssl', 'pkeyutl', '-sign',
- '-in', srctop_file('test', 'certs', 'sm2.crt'),
- '-inkey', srctop_file('test', 'certs', 'sm2.key'),
- '-out', 'signature.sm2', '-rawin',
- '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid'])));
-}
-
-sub verify
-{
- # Utilize the sm2.crt as the TBS file
- return run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin',
- '-in', srctop_file('test', 'certs', 'sm2.crt'),
- '-inkey', srctop_file('test', 'certs', 'sm2.crt'),
- '-sigfile', 'signature.sm2', '-rawin',
- '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid'])));
-}
+# For the tests below we use the cert itself as the TBS file
SKIP: {
skip "Skipping tests that require EC, SM2 or SM3", 2
if disabled("ec") || disabled("sm2") || disabled("sm3");
- ok(sign, "Sign a piece of data using SM2");
- ok(verify, "Verify an SM2 signature against a piece of data");
+ # SM2
+ ok(run(app(([ 'openssl', 'pkeyutl', '-sign',
+ '-in', srctop_file('test', 'certs', 'sm2.pem'),
+ '-inkey', srctop_file('test', 'certs', 'sm2.key'),
+ '-out', 'signature.dat', '-rawin',
+ '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))),
+ "Sign a piece of data using SM2");
+ ok(run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin',
+ '-in', srctop_file('test', 'certs', 'sm2.pem'),
+ '-inkey', srctop_file('test', 'certs', 'sm2.pem'),
+ '-sigfile', 'signature.dat', '-rawin',
+ '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid']))),
+ "Verify an SM2 signature against a piece of data");
}
-unlink 'signature.sm2';
+unlink 'signature.dat';
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index ffa48ed..b340833 100644
--- a/test/recipes/25-test_verify.t
+++ b/test/recipes/25-test_verify.t
@@ -27,7 +27,7 @@ sub verify {
run(app([@args]));
}
-plan tests => 146;
+plan tests => 148;
# Canonical success
ok(verify("ee-cert", "sslserver", ["root-cert"], ["ca-cert"]),
@@ -409,3 +409,15 @@ SKIP: {
"ED25519 signature");
}
+
+SKIP: {
+ skip "SM2 is not supported by this OpenSSL build", 1
+ if disabled("sm2");
+
+ # Test '-sm2-id' and '-sm2-hex-id' option
+ ok(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-id", "1234567812345678"),
+ "SM2 ID test");
+ ok(verify("sm2", "any", ["sm2-ca-cert"], [], "-sm2-hex-id",
+ "31323334353637383132333435363738"),
+ "SM2 hex ID test");
+}
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,29 @@
From 7e64be50900c4aa8cd040c4e3999540883bdeeb6 Mon Sep 17 00:00:00 2001
From: Paul Yang <kaishen.yy@antfin.com>
Date: Thu, 26 Sep 2019 10:57:23 +0800
Subject: [PATCH 13/15] Fix a document description in apps/req
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9958)
---
doc/man1/req.pod | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/doc/man1/req.pod b/doc/man1/req.pod
index 7b00bad..e117ec6 100644
--- a/doc/man1/req.pod
+++ b/doc/man1/req.pod
@@ -348,8 +348,8 @@ string is required by the SM2 signature algorithm for signing and verification.
=item B<-sm2-hex-id>
-Specify a binary ID string to use when signing or verifying using an SM2
-certificate. The argument for this option is string of hexadecimal digits.
+Specify a binary ID string to use when verifying an SM2 certificate request. The
+argument for this option is string of hexadecimal digits.
=back
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,121 @@
From a63238684c1d2e15f417f766f44418a8b52ef383 Mon Sep 17 00:00:00 2001
From: Paul Yang <kaishen.yy@antfin.com>
Date: Sat, 21 Sep 2019 00:32:57 +0800
Subject: [PATCH 12/15] Fix a double free issue when signing SM2 cert
If the SM2 ID value has not been passed correctly when signing an SM2
certificate/certificate request, a double free occurs. For instance:
openssl req -x509 ... -sm2-id 1234567812345678
The '-sm2-id' should not be used in this scenario, while the '-sigopt' is
the correct one to use. Documentation has also been updated to make the
options more clear.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9958)
---
apps/req.c | 48 ++++++++++++++++++++++++++++++------------------
doc/man1/req.pod | 4 ++--
2 files changed, 32 insertions(+), 20 deletions(-)
diff --git a/apps/req.c b/apps/req.c
index 96f1edd..95dd0e4 100644
--- a/apps/req.c
+++ b/apps/req.c
@@ -1756,15 +1756,19 @@ int do_X509_sign(X509 *x, EVP_PKEY *pkey, const EVP_MD *md,
#endif
rv = do_sign_init(mctx, pkey, md, sigopts);
- if (rv > 0)
+ if (rv > 0) {
rv = X509_sign_ctx(x, mctx);
#ifndef OPENSSL_NO_SM2
- /* only in SM2 case we need to free the pctx explicitly */
- if (ec_pkey_is_sm2(pkey)) {
- pctx = EVP_MD_CTX_pkey_ctx(mctx);
- EVP_PKEY_CTX_free(pctx);
- }
+ /*
+ * only in SM2 case we need to free the pctx explicitly
+ * if do_sign_init() fails, pctx is already freed in it
+ */
+ if (ec_pkey_is_sm2(pkey)) {
+ pctx = EVP_MD_CTX_pkey_ctx(mctx);
+ EVP_PKEY_CTX_free(pctx);
+ }
#endif
+ }
EVP_MD_CTX_free(mctx);
return rv > 0 ? 1 : 0;
}
@@ -1779,15 +1783,19 @@ int do_X509_REQ_sign(X509_REQ *x, EVP_PKEY *pkey, const EVP_MD *md,
#endif
rv = do_sign_init(mctx, pkey, md, sigopts);
- if (rv > 0)
+ if (rv > 0) {
rv = X509_REQ_sign_ctx(x, mctx);
#ifndef OPENSSL_NO_SM2
- /* only in SM2 case we need to free the pctx explicitly */
- if (ec_pkey_is_sm2(pkey)) {
- pctx = EVP_MD_CTX_pkey_ctx(mctx);
- EVP_PKEY_CTX_free(pctx);
- }
+ /*
+ * only in SM2 case we need to free the pctx explicitly
+ * if do_sign_init() fails, pctx is already freed in it
+ */
+ if (ec_pkey_is_sm2(pkey)) {
+ pctx = EVP_MD_CTX_pkey_ctx(mctx);
+ EVP_PKEY_CTX_free(pctx);
+ }
#endif
+ }
EVP_MD_CTX_free(mctx);
return rv > 0 ? 1 : 0;
}
@@ -1802,15 +1810,19 @@ int do_X509_CRL_sign(X509_CRL *x, EVP_PKEY *pkey, const EVP_MD *md,
#endif
rv = do_sign_init(mctx, pkey, md, sigopts);
- if (rv > 0)
+ if (rv > 0) {
rv = X509_CRL_sign_ctx(x, mctx);
#ifndef OPENSSL_NO_SM2
- /* only in SM2 case we need to free the pctx explicitly */
- if (ec_pkey_is_sm2(pkey)) {
- pctx = EVP_MD_CTX_pkey_ctx(mctx);
- EVP_PKEY_CTX_free(pctx);
- }
+ /*
+ * only in SM2 case we need to free the pctx explicitly
+ * if do_sign_init() fails, no need to double free pctx
+ */
+ if (ec_pkey_is_sm2(pkey)) {
+ pctx = EVP_MD_CTX_pkey_ctx(mctx);
+ EVP_PKEY_CTX_free(pctx);
+ }
#endif
+ }
EVP_MD_CTX_free(mctx);
return rv > 0 ? 1 : 0;
}
diff --git a/doc/man1/req.pod b/doc/man1/req.pod
index 3b9fcc3..7b00bad 100644
--- a/doc/man1/req.pod
+++ b/doc/man1/req.pod
@@ -343,8 +343,8 @@ for key generation operations.
=item B<-sm2-id>
-Specify the ID string to use when verifying an SM2 certificate. The ID string is
-required by the SM2 signature algorithm for signing and verification.
+Specify the ID string to use when verifying an SM2 certificate request. The ID
+string is required by the SM2 signature algorithm for signing and verification.
=item B<-sm2-hex-id>
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,43 @@
From 1c243548ef736329b08344ad9191803e5a93ec17 Mon Sep 17 00:00:00 2001
From: Paul Yang <yang.yang@baishancloud.com>
Date: Wed, 13 Mar 2019 18:04:05 +0800
Subject: [PATCH 07/15] Fix a memleak in apps/verify
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8465)
---
apps/verify.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/apps/verify.c b/apps/verify.c
index 09b31cf..5052d80 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -80,6 +80,7 @@ int verify_main(int argc, char **argv)
OPTION_CHOICE o;
unsigned char *sm2_id = NULL;
size_t sm2_idlen = 0;
+ int sm2_free = 0;
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
goto end;
@@ -174,6 +175,7 @@ int verify_main(int argc, char **argv)
break;
case OPT_SM2HEXID:
/* try to parse the input as hex string first */
+ sm2_free = 1;
sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
if (sm2_id == NULL) {
BIO_printf(bio_err, "Invalid hex string input\n");
@@ -216,6 +218,8 @@ int verify_main(int argc, char **argv)
}
end:
+ if (sm2_free)
+ OPENSSL_free(sm2_id);
X509_VERIFY_PARAM_free(vpm);
X509_STORE_free(store);
sk_X509_pop_free(untrusted, X509_free);
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,67 @@
From 380cf570be1ded495141e16ceab7afb7f7c57ab7 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Thu, 28 Feb 2019 13:47:26 +0000
Subject: [PATCH 02/15] Fix no-ec, no-sm2 and no-sm3
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8372)
---
apps/pkeyutl.c | 11 +++++++----
test/recipes/20-test_pkeyutl.t | 9 +++++++--
2 files changed, 14 insertions(+), 6 deletions(-)
diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c
index bca0464..1d3d57b 100644
--- a/apps/pkeyutl.c
+++ b/apps/pkeyutl.c
@@ -473,14 +473,16 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
}
ctx = EVP_PKEY_CTX_new_id(kdfnid, impl);
} else {
- EC_KEY *eckey = NULL;
- const EC_GROUP *group = NULL;
- int nid;
-
if (pkey == NULL)
goto end;
+
+#ifndef OPENSSL_NO_EC
/* SM2 needs a special treatment */
if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
+ EC_KEY *eckey = NULL;
+ const EC_GROUP *group = NULL;
+ int nid;
+
if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL
|| (group = EC_KEY_get0_group(eckey)) == NULL
|| (nid = EC_GROUP_get_curve_name(group)) == 0)
@@ -488,6 +490,7 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
if (nid == NID_sm2)
EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
}
+#endif
*pkeysize = EVP_PKEY_size(pkey);
ctx = EVP_PKEY_CTX_new(pkey, impl);
if (ppkey != NULL)
diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t
index a051138..1457530 100644
--- a/test/recipes/20-test_pkeyutl.t
+++ b/test/recipes/20-test_pkeyutl.t
@@ -37,7 +37,12 @@ sub verify
'-digest', 'sm3', '-pkeyopt', 'sm2_id:someid'])));
}
-ok(sign, "Sign a piece of data using SM2");
-ok(verify, "Verify an SM2 signature against a piece of data");
+SKIP: {
+ skip "Skipping tests that require EC, SM2 or SM3", 2
+ if disabled("ec") || disabled("sm2") || disabled("sm3");
+
+ ok(sign, "Sign a piece of data using SM2");
+ ok(verify, "Verify an SM2 signature against a piece of data");
+}
unlink 'signature.sm2';
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,44 @@
From 908570d02b683195ddfdc8e8c324638bfaa0d2c2 Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Thu, 14 Mar 2019 11:14:38 +0000
Subject: [PATCH 04/15] Guard some SM2 functions with OPENSSL_NO_SM2
Fixes the no-ec build
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8481)
---
include/openssl/x509.h | 2 ++
util/libcrypto.num | 4 ++--
2 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 5f17057..5c88251 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -573,8 +573,10 @@ void X509_get0_signature(const ASN1_BIT_STRING **psig,
const X509_ALGOR **palg, const X509 *x);
int X509_get_signature_nid(const X509 *x);
+# ifndef OPENSSL_NO_SM2
void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
+# endif
int X509_trusted(const X509 *x);
int X509_alias_set1(X509 *x, const unsigned char *name, int len);
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 8635ac4..233d1c7 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4626,5 +4626,5 @@ FIPS_drbg_get_strength 6379 1_1_0g EXIST::FUNCTION:
FIPS_rand_strength 6380 1_1_0g EXIST::FUNCTION:
FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION:
FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION:
-X509_set_sm2_id 6383 1_1_1m EXIST::FUNCTION:
-X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:
+X509_set_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2
+X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:SM2
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,320 @@
From 0717cc33d72b011cce4f53661c58d628b684275c Mon Sep 17 00:00:00 2001
From: Paul Yang <yang.yang@baishancloud.com>
Date: Mon, 1 Apr 2019 10:21:53 +0900
Subject: [PATCH 09/15] Make X509_set_sm2_id consistent with other setters
This commit makes the X509_set_sm2_id to 'set0' behaviour, which means
the memory management is passed to X509 and user doesn't need to free
the sm2_id parameter later. API name also changes to X509_set0_sm2_id.
Document and test case are also updated.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8626)
---
apps/verify.c | 40 +++++++++++++++++++-----------
crypto/x509/x_all.c | 5 +++-
crypto/x509/x_x509.c | 13 +++++++---
doc/man3/X509_get0_sm2_id.pod | 12 ++++++---
include/crypto/x509.h | 2 +-
include/openssl/x509.h | 2 +-
test/verify_extra_test.c | 46 +++++++++++++++++++++++++++++++++++
util/libcrypto.num | 2 +-
8 files changed, 97 insertions(+), 25 deletions(-)
diff --git a/apps/verify.c b/apps/verify.c
index 5052d80..9000567 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -246,27 +246,37 @@ static int check(X509_STORE *ctx, const char *file,
if (sm2id != NULL) {
#ifndef OPENSSL_NO_SM2
- ASN1_OCTET_STRING v;
+ ASN1_OCTET_STRING *v;
- v.data = sm2id;
- v.length = sm2idlen;
+ v = ASN1_OCTET_STRING_new();
+ if (v == NULL) {
+ BIO_printf(bio_err, "error: SM2 ID allocation failed\n");
+ goto end;
+ }
- X509_set_sm2_id(x, &v);
+ if (!ASN1_OCTET_STRING_set(v, sm2id, sm2idlen)) {
+ BIO_printf(bio_err, "error: setting SM2 ID failed\n");
+ ASN1_OCTET_STRING_free(v);
+ goto end;
+ }
+
+ X509_set0_sm2_id(x, v);
#endif
}
csc = X509_STORE_CTX_new();
if (csc == NULL) {
- printf("error %s: X.509 store context allocation failed\n",
- (file == NULL) ? "stdin" : file);
+ BIO_printf(bio_err, "error %s: X.509 store context allocation failed\n",
+ (file == NULL) ? "stdin" : file);
goto end;
}
X509_STORE_set_flags(ctx, vflags);
if (!X509_STORE_CTX_init(csc, ctx, x, uchain)) {
X509_STORE_CTX_free(csc);
- printf("error %s: X.509 store context initialization failed\n",
- (file == NULL) ? "stdin" : file);
+ BIO_printf(bio_err,
+ "error %s: X.509 store context initialization failed\n",
+ (file == NULL) ? "stdin" : file);
goto end;
}
if (tchain != NULL)
@@ -275,28 +285,30 @@ static int check(X509_STORE *ctx, const char *file,
X509_STORE_CTX_set0_crls(csc, crls);
i = X509_verify_cert(csc);
if (i > 0 && X509_STORE_CTX_get_error(csc) == X509_V_OK) {
- printf("%s: OK\n", (file == NULL) ? "stdin" : file);
+ BIO_printf(bio_out, "%s: OK\n", (file == NULL) ? "stdin" : file);
ret = 1;
if (show_chain) {
int j;
chain = X509_STORE_CTX_get1_chain(csc);
num_untrusted = X509_STORE_CTX_get_num_untrusted(csc);
- printf("Chain:\n");
+ BIO_printf(bio_out, "Chain:\n");
for (j = 0; j < sk_X509_num(chain); j++) {
X509 *cert = sk_X509_value(chain, j);
- printf("depth=%d: ", j);
+ BIO_printf(bio_out, "depth=%d: ", j);
X509_NAME_print_ex_fp(stdout,
X509_get_subject_name(cert),
0, get_nameopt());
if (j < num_untrusted)
- printf(" (untrusted)");
- printf("\n");
+ BIO_printf(bio_out, " (untrusted)");
+ BIO_printf(bio_out, "\n");
}
sk_X509_pop_free(chain, X509_free);
}
} else {
- printf("error %s: verification failed\n", (file == NULL) ? "stdin" : file);
+ BIO_printf(bio_err,
+ "error %s: verification failed\n",
+ (file == NULL) ? "stdin" : file);
}
X509_STORE_CTX_free(csc);
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index 60a2892..9c8aea5 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -72,7 +72,10 @@ static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid)
ret = 0;
goto err;
}
- if (EVP_PKEY_CTX_set1_id(pctx, x->sm2_id.data, x->sm2_id.length) != 1) {
+ /* NOTE: we tolerate no actual ID, to provide maximum flexibility */
+ if (x->sm2_id != NULL
+ && EVP_PKEY_CTX_set1_id(pctx, x->sm2_id->data,
+ x->sm2_id->length) != 1) {
X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
ret = 0;
goto err;
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index 1beab78..fb03bb2 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -72,6 +72,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
#ifndef OPENSSL_NO_RFC3779
ret->rfc3779_addr = NULL;
ret->rfc3779_asid = NULL;
+#endif
+#ifndef OPENSSL_NO_SM2
+ ret->sm2_id = NULL;
#endif
ret->aux = NULL;
ret->crldp = NULL;
@@ -91,6 +94,9 @@ static int x509_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
#ifndef OPENSSL_NO_RFC3779
sk_IPAddressFamily_pop_free(ret->rfc3779_addr, IPAddressFamily_free);
ASIdentifiers_free(ret->rfc3779_asid);
+#endif
+#ifndef OPENSSL_NO_SM2
+ ASN1_OCTET_STRING_free(ret->sm2_id);
#endif
break;
@@ -247,13 +253,14 @@ int X509_get_signature_nid(const X509 *x)
}
#ifndef OPENSSL_NO_SM2
-void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id)
+void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id)
{
- x->sm2_id = *sm2_id;
+ ASN1_OCTET_STRING_free(x->sm2_id);
+ x->sm2_id = sm2_id;
}
ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x)
{
- return &x->sm2_id;
+ return x->sm2_id;
}
#endif
diff --git a/doc/man3/X509_get0_sm2_id.pod b/doc/man3/X509_get0_sm2_id.pod
index 84da71e..9698c86 100644
--- a/doc/man3/X509_get0_sm2_id.pod
+++ b/doc/man3/X509_get0_sm2_id.pod
@@ -2,20 +2,24 @@
=head1 NAME
-X509_get0_sm2_id, X509_set_sm2_id - get or set SM2 ID for certificate operations
+X509_get0_sm2_id, X509_set0_sm2_id - get or set SM2 ID for certificate operations
=head1 SYNOPSIS
#include <openssl/x509.h>
ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
- void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
+ void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
=head1 DESCRIPTION
X509_get0_sm2_id() gets the ID value of an SM2 certificate B<x> by returning an
B<ASN1_OCTET_STRING> object which should not be freed by the caller.
-X509_set_sm2_id() sets the B<sm2_id> value to an SM2 certificate B<x>.
+
+X509_set0_sm2_id() sets the B<sm2_id> value to an SM2 certificate B<x>. Calling
+this function transfers the memory management of the value to the X509 object,
+and therefore the value that has been passed in should not be freed by the
+caller after this function has been called.
=head1 NOTES
@@ -25,7 +29,7 @@ ability to set and retrieve the SM2 ID value.
=head1 RETURN VALUES
-X509_set_sm2_id() does not return a value.
+X509_set0_sm2_id() does not return a value.
=head1 SEE ALSO
diff --git a/include/crypto/x509.h b/include/crypto/x509.h
index 418c427..5c314a8 100644
--- a/include/crypto/x509.h
+++ b/include/crypto/x509.h
@@ -186,7 +186,7 @@ struct x509_st {
CRYPTO_RWLOCK *lock;
volatile int ex_cached;
# ifndef OPENSSL_NO_SM2
- ASN1_OCTET_STRING sm2_id;
+ ASN1_OCTET_STRING *sm2_id;
# endif
} /* X509 */ ;
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 5c88251..a02cf50 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -574,7 +574,7 @@ void X509_get0_signature(const ASN1_BIT_STRING **psig,
int X509_get_signature_nid(const X509 *x);
# ifndef OPENSSL_NO_SM2
-void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
+void X509_set0_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
# endif
diff --git a/test/verify_extra_test.c b/test/verify_extra_test.c
index b9959e0..763ea4f 100644
--- a/test/verify_extra_test.c
+++ b/test/verify_extra_test.c
@@ -8,6 +8,7 @@
*/
#include <stdio.h>
+#include <string.h>
#include <openssl/crypto.h>
#include <openssl/bio.h>
#include <openssl/x509.h>
@@ -231,6 +232,48 @@ static int test_self_signed_bad(void)
return test_self_signed(bad_f, 0);
}
+#ifndef OPENSSL_NO_SM2
+static int test_sm2_id(void)
+{
+ /* we only need an X509 structure, no matter if it's a real SM2 cert */
+ X509 *x = NULL;
+ BIO *bio = NULL;
+ int ret = 0;
+ ASN1_OCTET_STRING *v = NULL, *v2 = NULL;
+ char *sm2id = "this is an ID";
+
+ bio = BIO_new_file(bad_f, "r");
+ if (bio == NULL)
+ goto err;
+
+ x = PEM_read_bio_X509(bio, NULL, 0, NULL);
+ if (x == NULL)
+ goto err;
+
+ v = ASN1_OCTET_STRING_new();
+ if (v == NULL)
+ goto err;
+
+ if (!ASN1_OCTET_STRING_set(v, (unsigned char *)sm2id, (int)strlen(sm2id))) {
+ ASN1_OCTET_STRING_free(v);
+ goto err;
+ }
+
+ X509_set0_sm2_id(x, v);
+
+ v2 = X509_get0_sm2_id(x);
+ if (!TEST_ptr(v2)
+ || !TEST_int_eq(ASN1_OCTET_STRING_cmp(v, v2), 0))
+ goto err;
+
+ ret = 1;
+ err:
+ X509_free(x);
+ BIO_free(bio);
+ return ret;
+}
+#endif
+
int setup_tests(void)
{
if (!TEST_ptr(roots_f = test_get_argument(0))
@@ -245,5 +288,8 @@ int setup_tests(void)
ADD_TEST(test_store_ctx);
ADD_TEST(test_self_signed_good);
ADD_TEST(test_self_signed_bad);
+#ifndef OPENSSL_NO_SM2
+ ADD_TEST(test_sm2_id);
+#endif
return 1;
}
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 233d1c7..d7abe91 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4626,5 +4626,5 @@ FIPS_drbg_get_strength 6379 1_1_0g EXIST::FUNCTION:
FIPS_rand_strength 6380 1_1_0g EXIST::FUNCTION:
FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION:
FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION:
-X509_set_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2
+X509_set0_sm2_id 6383 1_1_1m EXIST::FUNCTION:SM2
X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:SM2
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,492 @@
From 4d2e328357ac4b468d4762a5a5f615d7e7bf46a6 Mon Sep 17 00:00:00 2001
From: Xu Yizhou <xuyizhou1@huawei.com>
Date: Thu, 27 Oct 2022 20:49:34 +0800
Subject: [PATCH 1/3] SM3 acceleration with SM3 hardware instruction on aarch64
This patch contains the following two PRs,
1. SM3 acceleration with SM3 hardware instruction on aarch64
SM3 hardware instruction is optional feature of crypto extension for
aarch64. This implementation accelerates SM3 via SM3 instructions. For
the platform not supporting SM3 instruction, the original C
implementation still works. Thanks to AliBaba for testing and reporting
the following perf numbers for Yitian710:
Benchmark on T-Head Yitian-710 2.75GHz:
Before:
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
sm3 49297.82k 121062.63k 223106.05k 283371.52k 307574.10k 309400.92k
After (33% - 74% faster):
type 16 bytes 64 bytes 256 bytes 1024 bytes 8192 bytes 16384 bytes
sm3 65640.01k 179121.79k 359854.59k 481448.96k 534055.59k 538274.47k
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17454)
2. Fix sm3ss1 translation issue in sm3-armv8.pl
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/17542)
Signed-off-by: Xu Yizhou <xuyizhou1@huawei.com>
---
Configurations/00-base-templates.conf | 1 +
Configure | 4 +
crypto/arm64cpuid.pl | 7 +
crypto/arm_arch.h | 1 +
crypto/armcap.c | 10 +
crypto/sm3/asm/sm3-armv8.pl | 280 ++++++++++++++++++++++++++
crypto/sm3/build.info | 15 +-
crypto/sm3/sm3_local.h | 16 +-
8 files changed, 332 insertions(+), 2 deletions(-)
create mode 100644 crypto/sm3/asm/sm3-armv8.pl
diff --git a/Configurations/00-base-templates.conf b/Configurations/00-base-templates.conf
index 1d35012..a67ae65 100644
--- a/Configurations/00-base-templates.conf
+++ b/Configurations/00-base-templates.conf
@@ -322,6 +322,7 @@ my %targets=(
poly1305_asm_src=> "poly1305-armv8.S",
keccak1600_asm_src => "keccak1600-armv8.S",
sm4_asm_src => "vpsm4_ex-armv8.S",
+ sm3_asm_src => "sm3-armv8.S",
},
parisc11_asm => {
template => 1,
diff --git a/Configure b/Configure
index 3bfe360..fce460d 100755
--- a/Configure
+++ b/Configure
@@ -1423,6 +1423,9 @@ unless ($disabled{asm}) {
if ($target{sm4_asm_src} ne "") {
push @{$config{lib_defines}}, "VPSM4_EX_ASM";
}
+ if ($target{sm3_asm_src} ne "") {
+ push @{$config{lib_defines}}, "SM3_ASM";
+ }
}
my %predefined_C = compiler_predefined($config{CROSS_COMPILE}.$config{CC});
@@ -3379,6 +3382,7 @@ sub print_table_entry
"multilib",
"build_scheme",
"sm4_asm_src",
+ "sm3_asm_src",
);
if ($type eq "TABLE") {
diff --git a/crypto/arm64cpuid.pl b/crypto/arm64cpuid.pl
index 319927e..1e9b167 100755
--- a/crypto/arm64cpuid.pl
+++ b/crypto/arm64cpuid.pl
@@ -78,6 +78,13 @@ _armv8_sha512_probe:
ret
.size _armv8_sha512_probe,.-_armv8_sha512_probe
+.globl _armv8_sm3_probe
+.type _armv8_sm3_probe,%function
+_armv8_sm3_probe:
+ .long 0xce63c004 // sm3partw1 v4.4s, v0.4s, v3.4s
+ ret
+.size _armv8_sm3_probe,.-_armv8_sm3_probe
+
.globl OPENSSL_cleanse
.type OPENSSL_cleanse,%function
.align 5
diff --git a/crypto/arm_arch.h b/crypto/arm_arch.h
index 8b71055..8839b21 100644
--- a/crypto/arm_arch.h
+++ b/crypto/arm_arch.h
@@ -80,5 +80,6 @@ extern unsigned int OPENSSL_armcap_P;
# define ARMV8_SHA256 (1<<4)
# define ARMV8_PMULL (1<<5)
# define ARMV8_SHA512 (1<<6)
+# define ARMV8_SM3 (1<<9)
#endif
diff --git a/crypto/armcap.c b/crypto/armcap.c
index 48c5d4d..8b2f4a5 100644
--- a/crypto/armcap.c
+++ b/crypto/armcap.c
@@ -47,6 +47,7 @@ void _armv8_sha1_probe(void);
void _armv8_sha256_probe(void);
void _armv8_pmull_probe(void);
# ifdef __aarch64__
+void _armv8_sm3_probe(void);
void _armv8_sha512_probe(void);
# endif
uint32_t _armv7_tick(void);
@@ -130,6 +131,7 @@ static unsigned long getauxval(unsigned long key)
# define HWCAP_CE_PMULL (1 << 4)
# define HWCAP_CE_SHA1 (1 << 5)
# define HWCAP_CE_SHA256 (1 << 6)
+# define HWCAP_CE_SM3 (1 << 18)
# define HWCAP_CE_SHA512 (1 << 21)
# endif
@@ -190,6 +192,9 @@ void OPENSSL_cpuid_setup(void)
# ifdef __aarch64__
if (hwcap & HWCAP_CE_SHA512)
OPENSSL_armcap_P |= ARMV8_SHA512;
+
+ if (hwcap & HWCAP_CE_SM3)
+ OPENSSL_armcap_P |= ARMV8_SM3;
# endif
}
# endif
@@ -233,6 +238,11 @@ void OPENSSL_cpuid_setup(void)
_armv8_sha512_probe();
OPENSSL_armcap_P |= ARMV8_SHA512;
}
+
+ if (sigsetjmp(ill_jmp, 1) == 0) {
+ _armv8_sm3_probe();
+ OPENSSL_armcap_P |= ARMV8_SM3;
+ }
# endif
}
# endif
diff --git a/crypto/sm3/asm/sm3-armv8.pl b/crypto/sm3/asm/sm3-armv8.pl
new file mode 100644
index 0000000..677ca52
--- /dev/null
+++ b/crypto/sm3/asm/sm3-armv8.pl
@@ -0,0 +1,280 @@
+#! /usr/bin/env perl
+# Copyright 2021-2022 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+#
+# This module implements support for Armv8 SM3 instructions
+
+# $output is the last argument if it looks like a file (it has an extension)
+# $flavour is the first argument if it doesn't look like a file
+$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
+
+$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
+( $xlate="${dir}arm-xlate.pl" and -f $xlate ) or
+( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
+die "can't locate arm-xlate.pl";
+
+open OUT,"| \"$^X\" $xlate $flavour \"$output\""
+ or die "can't call $xlate: $!";
+*STDOUT=*OUT;
+
+# Message expanding:
+# Wj <- P1(W[j-16]^W[j-9]^(W[j-3]<<<15))^(W[j-13]<<<7)^W[j-6]
+# Input: s0, s1, s2, s3
+# s0 = w0 | w1 | w2 | w3
+# s1 = w4 | w5 | w6 | w7
+# s2 = w8 | w9 | w10 | w11
+# s3 = w12 | w13 | w14 | w15
+# Output: s4
+sub msg_exp () {
+my $s0 = shift;
+my $s1 = shift;
+my $s2 = shift;
+my $s3 = shift;
+my $s4 = shift;
+my $vtmp1 = shift;
+my $vtmp2 = shift;
+$code.=<<___;
+ // s4 = w7 | w8 | w9 | w10
+ ext $s4.16b, $s1.16b, $s2.16b, #12
+ // vtmp1 = w3 | w4 | w5 | w6
+ ext $vtmp1.16b, $s0.16b, $s1.16b, #12
+ // vtmp2 = w10 | w11 | w12 | w13
+ ext $vtmp2.16b, $s2.16b, $s3.16b, #8
+ sm3partw1 $s4.4s, $s0.4s, $s3.4s
+ sm3partw2 $s4.4s, $vtmp2.4s, $vtmp1.4s
+___
+}
+
+# A round of compresson function
+# Input:
+# ab - choose instruction among sm3tt1a, sm3tt1b, sm3tt2a, sm3tt2b
+# vstate0 - vstate1, store digest status(A - H)
+# vconst0 - vconst1, interleaved used to store Tj <<< j
+# vtmp - temporary register
+# vw - for sm3tt1ab, vw = s0 eor s1
+# s0 - for sm3tt2ab, just be s0
+# i, choose wj' or wj from vw
+sub round () {
+my $ab = shift;
+my $vstate0 = shift;
+my $vstate1 = shift;
+my $vconst0 = shift;
+my $vconst1 = shift;
+my $vtmp = shift;
+my $vw = shift;
+my $s0 = shift;
+my $i = shift;
+$code.=<<___;
+ sm3ss1 $vtmp.4s, $vstate0.4s, $vconst0.4s, $vstate1.4s
+ shl $vconst1.4s, $vconst0.4s, #1
+ sri $vconst1.4s, $vconst0.4s, #31
+ sm3tt1$ab $vstate0.4s, $vtmp.4s, $vw.4s[$i]
+ sm3tt2$ab $vstate1.4s, $vtmp.4s, $s0.4s[$i]
+___
+}
+
+sub qround () {
+my $ab = shift;
+my $vstate0 = shift;
+my $vstate1 = shift;
+my $vconst0 = shift;
+my $vconst1 = shift;
+my $vtmp1 = shift;
+my $vtmp2 = shift;
+my $s0 = shift;
+my $s1 = shift;
+my $s2 = shift;
+my $s3 = shift;
+my $s4 = shift;
+ if($s4) {
+ &msg_exp($s0, $s1, $s2, $s3, $s4, $vtmp1, $vtmp2);
+ }
+$code.=<<___;
+ eor $vtmp1.16b, $s0.16b, $s1.16b
+___
+ &round($ab, $vstate0, $vstate1, $vconst0, $vconst1, $vtmp2,
+ $vtmp1, $s0, 0);
+ &round($ab, $vstate0, $vstate1, $vconst1, $vconst0, $vtmp2,
+ $vtmp1, $s0, 1);
+ &round($ab, $vstate0, $vstate1, $vconst0, $vconst1, $vtmp2,
+ $vtmp1, $s0, 2);
+ &round($ab, $vstate0, $vstate1, $vconst1, $vconst0, $vtmp2,
+ $vtmp1, $s0, 3);
+}
+
+$code=<<___;
+#include "arm_arch.h"
+.arch armv8.2-a
+.text
+___
+
+{{{
+my ($pstate,$pdata,$num)=("x0","x1","w2");
+my ($state1,$state2)=("v5","v6");
+my ($sconst1, $sconst2)=("s16","s17");
+my ($vconst1, $vconst2)=("v16","v17");
+my ($s0,$s1,$s2,$s3,$s4)=map("v$_",(0..4));
+my ($bkstate1,$bkstate2)=("v18","v19");
+my ($vconst_tmp1,$vconst_tmp2)=("v20","v21");
+my ($vtmp1,$vtmp2)=("v22","v23");
+my $constaddr="x8";
+# void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num)
+$code.=<<___;
+.globl ossl_hwsm3_block_data_order
+.type ossl_hwsm3_block_data_order,%function
+.align 5
+ossl_hwsm3_block_data_order:
+ // load state
+ ld1 {$state1.4s-$state2.4s}, [$pstate]
+ rev64 $state1.4s, $state1.4s
+ rev64 $state2.4s, $state2.4s
+ ext $state1.16b, $state1.16b, $state1.16b, #8
+ ext $state2.16b, $state2.16b, $state2.16b, #8
+
+ adr $constaddr, .Tj
+ ldp $sconst1, $sconst2, [$constaddr]
+
+.Loop:
+ // load input
+ ld1 {$s0.16b-$s3.16b}, [$pdata], #64
+ sub $num, $num, #1
+
+ mov $bkstate1.16b, $state1.16b
+ mov $bkstate2.16b, $state2.16b
+
+#ifndef __ARMEB__
+ rev32 $s0.16b, $s0.16b
+ rev32 $s1.16b, $s1.16b
+ rev32 $s2.16b, $s2.16b
+ rev32 $s3.16b, $s3.16b
+#endif
+
+ ext $vconst_tmp1.16b, $vconst1.16b, $vconst1.16b, #4
+___
+ &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s0,$s1,$s2,$s3,$s4);
+ &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s1,$s2,$s3,$s4,$s0);
+ &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s2,$s3,$s4,$s0,$s1);
+ &qround("a",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s3,$s4,$s0,$s1,$s2);
+
+$code.=<<___;
+ ext $vconst_tmp1.16b, $vconst2.16b, $vconst2.16b, #4
+___
+
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s4,$s0,$s1,$s2,$s3);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s0,$s1,$s2,$s3,$s4);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s1,$s2,$s3,$s4,$s0);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s2,$s3,$s4,$s0,$s1);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s3,$s4,$s0,$s1,$s2);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s4,$s0,$s1,$s2,$s3);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s0,$s1,$s2,$s3,$s4);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s1,$s2,$s3,$s4,$s0);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s2,$s3,$s4,$s0,$s1);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s3,$s4);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s4,$s0);
+ &qround("b",$state1,$state2,$vconst_tmp1,$vconst_tmp2,$vtmp1,$vtmp2,
+ $s0,$s1);
+
+$code.=<<___;
+ eor $state1.16b, $state1.16b, $bkstate1.16b
+ eor $state2.16b, $state2.16b, $bkstate2.16b
+
+ // any remained blocks?
+ cbnz $num, .Loop
+
+ // save state
+ rev64 $state1.4s, $state1.4s
+ rev64 $state2.4s, $state2.4s
+ ext $state1.16b, $state1.16b, $state1.16b, #8
+ ext $state2.16b, $state2.16b, $state2.16b, #8
+ st1 {$state1.4s-$state2.4s}, [$pstate]
+ ret
+.size ossl_hwsm3_block_data_order,.-ossl_hwsm3_block_data_order
+
+.align 3
+.Tj:
+.word 0x79cc4519, 0x9d8a7a87
+___
+}}}
+
+#########################################
+my %sm3partopcode = (
+ "sm3partw1" => 0xce60C000,
+ "sm3partw2" => 0xce60C400);
+
+my %sm3ss1opcode = (
+ "sm3ss1" => 0xce400000);
+
+my %sm3ttopcode = (
+ "sm3tt1a" => 0xce408000,
+ "sm3tt1b" => 0xce408400,
+ "sm3tt2a" => 0xce408800,
+ "sm3tt2b" => 0xce408C00);
+
+sub unsm3part {
+ my ($mnemonic,$arg)=@_;
+
+ $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)/o
+ &&
+ sprintf ".inst\t0x%08x\t//%s %s",
+ $sm3partopcode{$mnemonic}|$1|($2<<5)|($3<<16),
+ $mnemonic,$arg;
+}
+
+sub unsm3ss1 {
+ my ($mnemonic,$arg)=@_;
+
+ $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)/o
+ &&
+ sprintf ".inst\t0x%08x\t//%s %s",
+ $sm3ss1opcode{$mnemonic}|$1|($2<<5)|($3<<16)|($4<<10),
+ $mnemonic,$arg;
+}
+
+sub unsm3tt {
+ my ($mnemonic,$arg)=@_;
+
+ $arg=~ m/[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*,\s*[qv](\d+)[^,]*\[([0-3])\]/o
+ &&
+ sprintf ".inst\t0x%08x\t//%s %s",
+ $sm3ttopcode{$mnemonic}|$1|($2<<5)|($3<<16)|($4<<12),
+ $mnemonic,$arg;
+}
+
+open SELF,$0;
+while(<SELF>) {
+ next if (/^#!/);
+ last if (!s/^#/\/\// and !/^$/);
+ print;
+}
+close SELF;
+
+foreach(split("\n",$code)) {
+ s/\`([^\`]*)\`/eval($1)/ge;
+
+ s/\b(sm3partw[1-2])\s+([qv].*)/unsm3part($1,$2)/ge;
+ s/\b(sm3ss1)\s+([qv].*)/unsm3ss1($1,$2)/ge;
+ s/\b(sm3tt[1-2][a-b])\s+([qv].*)/unsm3tt($1,$2)/ge;
+ print $_,"\n";
+}
+
+close STDOUT or die "error closing STDOUT: $!";
diff --git a/crypto/sm3/build.info b/crypto/sm3/build.info
index 6009b19..e113729 100644
--- a/crypto/sm3/build.info
+++ b/crypto/sm3/build.info
@@ -1,2 +1,15 @@
LIBS=../../libcrypto
-SOURCE[../../libcrypto]=sm3.c m_sm3.c
+SOURCE[../../libcrypto]=\
+ sm3.c m_sm3.c {- $target{sm3_asm_src} -}
+
+GENERATE[sm3-armv8.S]=asm/sm3-armv8.pl $(PERLASM_SCHEME)
+INCLUDE[sm3-armv8.o]=..
+
+BEGINRAW[Makefile]
+##### SM3 assembler implementations
+
+# GNU make "catch all"
+{- $builddir -}/sm3-%.S: {- $sourcedir -}/asm/sm3-%.pl
+ CC="$(CC)" $(PERL) $< $(PERLASM_SCHEME) $@
+
+ENDRAW[Makefile]
\ No newline at end of file
diff --git a/crypto/sm3/sm3_local.h b/crypto/sm3/sm3_local.h
index 7171de5..aafff63 100644
--- a/crypto/sm3/sm3_local.h
+++ b/crypto/sm3/sm3_local.h
@@ -32,7 +32,21 @@
ll=(c)->G; (void)HOST_l2c(ll, (s)); \
ll=(c)->H; (void)HOST_l2c(ll, (s)); \
} while (0)
-#define HASH_BLOCK_DATA_ORDER sm3_block_data_order
+
+#if defined(SM3_ASM)
+# if defined(__aarch64__)
+# include "crypto/arm_arch.h"
+# define HWSM3_CAPABLE (OPENSSL_armcap_P & ARMV8_SM3)
+void ossl_hwsm3_block_data_order(SM3_CTX *c, const void *p, size_t num);
+# endif
+#endif
+
+#if defined(HWSM3_CAPABLE)
+# define HASH_BLOCK_DATA_ORDER (HWSM3_CAPABLE ? ossl_hwsm3_block_data_order \
+ : sm3_block_data_order)
+#else
+# define HASH_BLOCK_DATA_ORDER sm3_block_data_order
+#endif
void sm3_transform(SM3_CTX *c, const unsigned char *data);
--
2.36.1

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,30 @@
From f0dd65378296590d87250bf2130bad567483ee3d Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Wed, 3 Apr 2019 09:44:41 +0100
Subject: [PATCH 08/15] Skip the correct number of tests if SM2 is disabled
Fixes no-sm2 (and also no-sm3 and no-ec)
Reviewed-by: Richard Levitte <levitte@openssl.org>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
(Merged from https://github.com/openssl/openssl/pull/8650)
---
test/recipes/25-test_verify.t | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/test/recipes/25-test_verify.t b/test/recipes/25-test_verify.t
index b340833..d254bd8 100644
--- a/test/recipes/25-test_verify.t
+++ b/test/recipes/25-test_verify.t
@@ -411,7 +411,7 @@ SKIP: {
}
SKIP: {
- skip "SM2 is not supported by this OpenSSL build", 1
+ skip "SM2 is not supported by this OpenSSL build", 2
if disabled("sm2");
# Test '-sm2-id' and '-sm2-hex-id' option
--
2.20.1 (Apple Git-117)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,579 @@
From 7d86ccd1282aeff8f6d564c5d37625ffcc048f2d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E6=9D=A8=E6=B4=8B?= <yang.yang@baishancloud.com>
Date: Fri, 26 Oct 2018 21:34:08 +0800
Subject: [PATCH 03/15] Support SM2 certificate verification
Reviewed-by: Tim Hudson <tjh@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8321)
---
apps/verify.c | 45 +++++++++++++--
crypto/asn1/a_verify.c | 3 +-
crypto/err/openssl.txt | 2 +
crypto/objects/obj_dat.h | 17 ++++--
crypto/objects/obj_mac.num | 1 +
crypto/objects/obj_xref.h | 4 +-
crypto/objects/obj_xref.txt | 2 +
crypto/objects/objects.txt | 2 +
crypto/x509/x509_err.c | 2 +
crypto/x509/x_all.c | 110 ++++++++++++++++++++++++++++++++++++
crypto/x509/x_x509.c | 12 ++++
fuzz/oids.txt | 1 +
include/crypto/x509.h | 5 +-
include/openssl/obj_mac.h | 7 ++-
include/openssl/x509.h | 3 +
include/openssl/x509err.h | 2 +
util/libcrypto.num | 2 +
17 files changed, 204 insertions(+), 16 deletions(-)
diff --git a/apps/verify.c b/apps/verify.c
index 1f93856..09b31cf 100644
--- a/apps/verify.c
+++ b/apps/verify.c
@@ -21,7 +21,8 @@
static int cb(int ok, X509_STORE_CTX *ctx);
static int check(X509_STORE *ctx, const char *file,
STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
- STACK_OF(X509_CRL) *crls, int show_chain);
+ STACK_OF(X509_CRL) *crls, int show_chain,
+ unsigned char *sm2id, size_t sm2idlen);
static int v_verbose = 0, vflags = 0;
typedef enum OPTION_choice {
@@ -29,7 +30,7 @@ typedef enum OPTION_choice {
OPT_ENGINE, OPT_CAPATH, OPT_CAFILE, OPT_NOCAPATH, OPT_NOCAFILE,
OPT_UNTRUSTED, OPT_TRUSTED, OPT_CRLFILE, OPT_CRL_DOWNLOAD, OPT_SHOW_CHAIN,
OPT_V_ENUM, OPT_NAMEOPT,
- OPT_VERBOSE
+ OPT_VERBOSE, OPT_SM2ID, OPT_SM2HEXID
} OPTION_CHOICE;
const OPTIONS verify_options[] = {
@@ -56,6 +57,12 @@ const OPTIONS verify_options[] = {
OPT_V_OPTIONS,
#ifndef OPENSSL_NO_ENGINE
{"engine", OPT_ENGINE, 's', "Use engine, possibly a hardware device"},
+#endif
+#ifndef OPENSSL_NO_SM2
+ {"sm2-id", OPT_SM2ID, 's',
+ "Specify an ID string to verify an SM2 certificate"},
+ {"sm2-hex-id", OPT_SM2HEXID, 's',
+ "Specify a hex ID string to verify an SM2 certificate"},
#endif
{NULL}
};
@@ -71,6 +78,8 @@ int verify_main(int argc, char **argv)
int noCApath = 0, noCAfile = 0;
int vpmtouched = 0, crl_download = 0, show_chain = 0, i = 0, ret = 1;
OPTION_CHOICE o;
+ unsigned char *sm2_id = NULL;
+ size_t sm2_idlen = 0;
if ((vpm = X509_VERIFY_PARAM_new()) == NULL)
goto end;
@@ -158,6 +167,19 @@ int verify_main(int argc, char **argv)
case OPT_VERBOSE:
v_verbose = 1;
break;
+ case OPT_SM2ID:
+ /* we assume the input is not a hex string */
+ sm2_id = (unsigned char *)opt_arg();
+ sm2_idlen = strlen((const char *)sm2_id);
+ break;
+ case OPT_SM2HEXID:
+ /* try to parse the input as hex string first */
+ sm2_id = OPENSSL_hexstr2buf(opt_arg(), (long *)&sm2_idlen);
+ if (sm2_id == NULL) {
+ BIO_printf(bio_err, "Invalid hex string input\n");
+ goto end;
+ }
+ break;
}
}
argc = opt_num_rest();
@@ -183,12 +205,13 @@ int verify_main(int argc, char **argv)
ret = 0;
if (argc < 1) {
- if (check(store, NULL, untrusted, trusted, crls, show_chain) != 1)
+ if (check(store, NULL, untrusted, trusted, crls, show_chain,
+ sm2_id, sm2_idlen) != 1)
ret = -1;
} else {
for (i = 0; i < argc; i++)
if (check(store, argv[i], untrusted, trusted, crls,
- show_chain) != 1)
+ show_chain, sm2_id, sm2_idlen) != 1)
ret = -1;
}
@@ -204,7 +227,8 @@ int verify_main(int argc, char **argv)
static int check(X509_STORE *ctx, const char *file,
STACK_OF(X509) *uchain, STACK_OF(X509) *tchain,
- STACK_OF(X509_CRL) *crls, int show_chain)
+ STACK_OF(X509_CRL) *crls, int show_chain,
+ unsigned char *sm2id, size_t sm2idlen)
{
X509 *x = NULL;
int i = 0, ret = 0;
@@ -216,6 +240,17 @@ static int check(X509_STORE *ctx, const char *file,
if (x == NULL)
goto end;
+ if (sm2id != NULL) {
+#ifndef OPENSSL_NO_SM2
+ ASN1_OCTET_STRING v;
+
+ v.data = sm2id;
+ v.length = sm2idlen;
+
+ X509_set_sm2_id(x, &v);
+#endif
+ }
+
csc = X509_STORE_CTX_new();
if (csc == NULL) {
printf("error %s: X.509 store context allocation failed\n",
diff --git a/crypto/asn1/a_verify.c b/crypto/asn1/a_verify.c
index 4b5f542..f543aa1 100644
--- a/crypto/asn1/a_verify.c
+++ b/crypto/asn1/a_verify.c
@@ -94,7 +94,7 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
int mdnid, pknid;
size_t inll = 0;
- if (!pkey) {
+ if (pkey == NULL) {
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
return -1;
}
@@ -150,7 +150,6 @@ int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
ret = 0;
goto err;
}
-
}
inl = ASN1_item_i2d(asn, &buf_in, it);
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 902e97b..5e71e65 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1766,8 +1766,10 @@ X509_F_X509_STORE_NEW:158:X509_STORE_new
X509_F_X509_TO_X509_REQ:126:X509_to_X509_REQ
X509_F_X509_TRUST_ADD:133:X509_TRUST_add
X509_F_X509_TRUST_SET:141:X509_TRUST_set
+X509_F_X509_VERIFY:161:X509_verify
X509_F_X509_VERIFY_CERT:127:X509_verify_cert
X509_F_X509_VERIFY_PARAM_NEW:159:X509_VERIFY_PARAM_new
+X509_F_X509_VERIFY_SM2:162:x509_verify_sm2
#Reason codes
ASN1_R_ADDING_OBJECT:171:adding object
diff --git a/crypto/objects/obj_dat.h b/crypto/objects/obj_dat.h
index 24b49a2..eb4cce4 100644
--- a/crypto/objects/obj_dat.h
+++ b/crypto/objects/obj_dat.h
@@ -2,7 +2,7 @@
* WARNING: do not edit!
* Generated by crypto/objects/obj_dat.pl
*
- * Copyright 1995-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1995-2022 The OpenSSL Project Authors. All Rights Reserved.
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
@@ -10,7 +10,7 @@
*/
/* Serialized OID's */
-static const unsigned char so[7762] = {
+static const unsigned char so[7770] = {
0x2A,0x86,0x48,0x86,0xF7,0x0D, /* [ 0] OBJ_rsadsi */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x01, /* [ 6] OBJ_pkcs */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x02, /* [ 13] OBJ_md2 */
@@ -1076,9 +1076,10 @@ static const unsigned char so[7762] = {
0x2A,0x85,0x03,0x07,0x01,0x02,0x01,0x01,0x04, /* [ 7736] OBJ_id_tc26_gost_3410_2012_256_paramSetD */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0C, /* [ 7745] OBJ_hmacWithSHA512_224 */
0x2A,0x86,0x48,0x86,0xF7,0x0D,0x02,0x0D, /* [ 7753] OBJ_hmacWithSHA512_256 */
+ 0x2A,0x81,0x1C,0xCF,0x55,0x01,0x83,0x75, /* [ 7761] OBJ_SM2_with_SM3 */
};
-#define NUM_NID 1195
+#define NUM_NID 1196
static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"UNDEF", "undefined", NID_undef},
{"rsadsi", "RSA Data Security, Inc.", NID_rsadsi, 6, &so[0]},
@@ -2275,9 +2276,10 @@ static const ASN1_OBJECT nid_objs[NUM_NID] = {
{"magma-mac", "magma-mac", NID_magma_mac},
{"hmacWithSHA512-224", "hmacWithSHA512-224", NID_hmacWithSHA512_224, 8, &so[7745]},
{"hmacWithSHA512-256", "hmacWithSHA512-256", NID_hmacWithSHA512_256, 8, &so[7753]},
+ {"SM2-SM3", "SM2-with-SM3", NID_SM2_with_SM3, 8, &so[7761]},
};
-#define NUM_SN 1186
+#define NUM_SN 1187
static const unsigned int sn_objs[NUM_SN] = {
364, /* "AD_DVCS" */
419, /* "AES-128-CBC" */
@@ -2543,6 +2545,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1100, /* "SHAKE128" */
1101, /* "SHAKE256" */
1172, /* "SM2" */
+ 1195, /* "SM2-SM3" */
1143, /* "SM3" */
1134, /* "SM4-CBC" */
1137, /* "SM4-CFB" */
@@ -3467,7 +3470,7 @@ static const unsigned int sn_objs[NUM_SN] = {
1093, /* "x509ExtAdmission" */
};
-#define NUM_LN 1186
+#define NUM_LN 1187
static const unsigned int ln_objs[NUM_LN] = {
363, /* "AD Time Stamping" */
405, /* "ANSI X9.62" */
@@ -3623,6 +3626,7 @@ static const unsigned int ln_objs[NUM_LN] = {
1119, /* "RSA-SHA3-512" */
188, /* "S/MIME" */
167, /* "S/MIME Capabilities" */
+ 1195, /* "SM2-with-SM3" */
1006, /* "SNILS" */
387, /* "SNMPv2" */
1025, /* "SSH Client" */
@@ -4657,7 +4661,7 @@ static const unsigned int ln_objs[NUM_LN] = {
125, /* "zlib compression" */
};
-#define NUM_OBJ 1071
+#define NUM_OBJ 1072
static const unsigned int obj_objs[NUM_OBJ] = {
0, /* OBJ_undef 0 */
181, /* OBJ_iso 1 */
@@ -5126,6 +5130,7 @@ static const unsigned int obj_objs[NUM_OBJ] = {
1139, /* OBJ_sm4_ctr 1 2 156 10197 1 104 7 */
1172, /* OBJ_sm2 1 2 156 10197 1 301 */
1143, /* OBJ_sm3 1 2 156 10197 1 401 */
+ 1195, /* OBJ_SM2_with_SM3 1 2 156 10197 1 501 */
1144, /* OBJ_sm3WithRSAEncryption 1 2 156 10197 1 504 */
776, /* OBJ_seed_ecb 1 2 410 200004 1 3 */
777, /* OBJ_seed_cbc 1 2 410 200004 1 4 */
diff --git a/crypto/objects/obj_mac.num b/crypto/objects/obj_mac.num
index 1b6a9c6..8b797b0 100644
--- a/crypto/objects/obj_mac.num
+++ b/crypto/objects/obj_mac.num
@@ -1192,3 +1192,4 @@ magma_cfb 1191
magma_mac 1192
hmacWithSHA512_224 1193
hmacWithSHA512_256 1194
+SM2_with_SM3 1195
diff --git a/crypto/objects/obj_xref.h b/crypto/objects/obj_xref.h
index 5c3561a..1acfcde 100644
--- a/crypto/objects/obj_xref.h
+++ b/crypto/objects/obj_xref.h
@@ -2,7 +2,7 @@
* WARNING: do not edit!
* Generated by objxref.pl
*
- * Copyright 1998-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 1998-2022 The OpenSSL Project Authors. All Rights Reserved.
*
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
@@ -79,6 +79,7 @@ static const nid_triple sigoid_srt[] = {
{NID_RSA_SHA3_256, NID_sha3_256, NID_rsaEncryption},
{NID_RSA_SHA3_384, NID_sha3_384, NID_rsaEncryption},
{NID_RSA_SHA3_512, NID_sha3_512, NID_rsaEncryption},
+ {NID_SM2_with_SM3, NID_sm3, NID_sm2},
};
static const nid_triple *const sigoid_srt_xref[] = {
@@ -125,4 +126,5 @@ static const nid_triple *const sigoid_srt_xref[] = {
&sigoid_srt[45],
&sigoid_srt[46],
&sigoid_srt[47],
+ &sigoid_srt[48],
};
diff --git a/crypto/objects/obj_xref.txt b/crypto/objects/obj_xref.txt
index ca3e744..f3dd8ed 100644
--- a/crypto/objects/obj_xref.txt
+++ b/crypto/objects/obj_xref.txt
@@ -64,3 +64,5 @@ dhSinglePass_cofactorDH_sha224kdf_scheme sha224 dh_cofactor_kdf
dhSinglePass_cofactorDH_sha256kdf_scheme sha256 dh_cofactor_kdf
dhSinglePass_cofactorDH_sha384kdf_scheme sha384 dh_cofactor_kdf
dhSinglePass_cofactorDH_sha512kdf_scheme sha512 dh_cofactor_kdf
+
+SM2_with_SM3 sm3 sm2
diff --git a/crypto/objects/objects.txt b/crypto/objects/objects.txt
index c49d4c5..be9da47 100644
--- a/crypto/objects/objects.txt
+++ b/crypto/objects/objects.txt
@@ -385,6 +385,8 @@ sm-scheme 301 : SM2 : sm2
sm-scheme 401 : SM3 : sm3
sm-scheme 504 : RSA-SM3 : sm3WithRSAEncryption
+sm-scheme 501 : SM2-SM3 : SM2-with-SM3
+
# From RFC4231
rsadsi 2 8 : : hmacWithSHA224
rsadsi 2 9 : : hmacWithSHA256
diff --git a/crypto/x509/x509_err.c b/crypto/x509/x509_err.c
index bdd1e67..c91ad7c 100644
--- a/crypto/x509/x509_err.c
+++ b/crypto/x509/x509_err.c
@@ -105,9 +105,11 @@ static const ERR_STRING_DATA X509_str_functs[] = {
{ERR_PACK(ERR_LIB_X509, X509_F_X509_TO_X509_REQ, 0), "X509_to_X509_REQ"},
{ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_ADD, 0), "X509_TRUST_add"},
{ERR_PACK(ERR_LIB_X509, X509_F_X509_TRUST_SET, 0), "X509_TRUST_set"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY, 0), "X509_verify"},
{ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_CERT, 0), "X509_verify_cert"},
{ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_PARAM_NEW, 0),
"X509_VERIFY_PARAM_new"},
+ {ERR_PACK(ERR_LIB_X509, X509_F_X509_VERIFY_SM2, 0), "x509_verify_sm2"},
{0, NULL}
};
diff --git a/crypto/x509/x_all.c b/crypto/x509/x_all.c
index a4e9cda..60a2892 100644
--- a/crypto/x509/x_all.c
+++ b/crypto/x509/x_all.c
@@ -19,10 +19,120 @@
#include <openssl/dsa.h>
#include <openssl/x509v3.h>
+#ifndef OPENSSL_NO_SM2
+
+# include "crypto/asn1.h"
+# include "crypto/evp.h"
+
+static int x509_verify_sm2(X509 *x, EVP_PKEY *pkey, int mdnid, int pknid)
+{
+ EVP_MD_CTX *ctx = NULL;
+ unsigned char *buf_in = NULL;
+ int ret = -1, inl = 0;
+ size_t inll = 0;
+ EVP_PKEY_CTX *pctx = NULL;
+ const EVP_MD *type = EVP_get_digestbynid(mdnid);
+
+ if (type == NULL) {
+ X509err(X509_F_X509_VERIFY_SM2,
+ ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
+ goto err;
+ }
+
+ if (pkey == NULL) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_PASSED_NULL_PARAMETER);
+ return -1;
+ }
+
+ if (x->signature.type == V_ASN1_BIT_STRING && x->signature.flags & 0x7) {
+ X509err(X509_F_X509_VERIFY_SM2, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
+ return -1;
+ }
+
+ ctx = EVP_MD_CTX_new();
+ if (ctx == NULL) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+
+ /* Check public key OID matches public key type */
+ if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
+ X509err(X509_F_X509_VERIFY_SM2, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
+ goto err;
+ }
+
+ if (!EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2)) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+ pctx = EVP_PKEY_CTX_new(pkey, NULL);
+ if (pctx == NULL) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+ if (EVP_PKEY_CTX_set1_id(pctx, x->sm2_id.data, x->sm2_id.length) != 1) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+ EVP_MD_CTX_set_pkey_ctx(ctx, pctx);
+
+ if (!EVP_DigestVerifyInit(ctx, NULL, type, NULL, pkey)) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
+ ret = 0;
+ goto err;
+ }
+
+ inl = ASN1_item_i2d((ASN1_VALUE *)&x->cert_info, &buf_in,
+ ASN1_ITEM_rptr(X509_CINF));
+ if (inl <= 0) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_INTERNAL_ERROR);
+ goto err;
+ }
+ if (buf_in == NULL) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_MALLOC_FAILURE);
+ goto err;
+ }
+ inll = inl;
+
+ ret = EVP_DigestVerify(ctx, x->signature.data,
+ (size_t)x->signature.length, buf_in, inl);
+ if (ret <= 0) {
+ X509err(X509_F_X509_VERIFY_SM2, ERR_R_EVP_LIB);
+ goto err;
+ }
+ ret = 1;
+ err:
+ OPENSSL_clear_free(buf_in, inll);
+ EVP_MD_CTX_free(ctx);
+ EVP_PKEY_CTX_free(pctx);
+ return ret;
+}
+#endif
+
int X509_verify(X509 *a, EVP_PKEY *r)
{
+#ifndef OPENSSL_NO_SM2
+ int mdnid, pknid;
+#endif
+
if (X509_ALGOR_cmp(&a->sig_alg, &a->cert_info.signature))
return 0;
+
+#ifndef OPENSSL_NO_SM2
+ /* Convert signature OID into digest and public key OIDs */
+ if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->sig_alg.algorithm),
+ &mdnid, &pknid)) {
+ X509err(X509_F_X509_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
+ return 0;
+ }
+
+ if (pknid == NID_sm2)
+ return x509_verify_sm2(a, r, mdnid, pknid);
+#endif
+
return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CINF), &a->sig_alg,
&a->signature, &a->cert_info, r));
}
diff --git a/crypto/x509/x_x509.c b/crypto/x509/x_x509.c
index 7aa8b77..1beab78 100644
--- a/crypto/x509/x_x509.c
+++ b/crypto/x509/x_x509.c
@@ -245,3 +245,15 @@ int X509_get_signature_nid(const X509 *x)
{
return OBJ_obj2nid(x->sig_alg.algorithm);
}
+
+#ifndef OPENSSL_NO_SM2
+void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id)
+{
+ x->sm2_id = *sm2_id;
+}
+
+ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x)
+{
+ return &x->sm2_id;
+}
+#endif
diff --git a/fuzz/oids.txt b/fuzz/oids.txt
index eda55e4..8dfdea9 100644
--- a/fuzz/oids.txt
+++ b/fuzz/oids.txt
@@ -1063,3 +1063,4 @@ OBJ_id_tc26_gost_3410_2012_256_paramSetC="\x2A\x85\x03\x07\x01\x02\x01\x01\x03"
OBJ_id_tc26_gost_3410_2012_256_paramSetD="\x2A\x85\x03\x07\x01\x02\x01\x01\x04"
OBJ_hmacWithSHA512_224="\x2A\x86\x48\x86\xF7\x0D\x02\x0C"
OBJ_hmacWithSHA512_256="\x2A\x86\x48\x86\xF7\x0D\x02\x0D"
+OBJ_SM2_with_SM3="\x2A\x81\x1C\xCF\x55\x01\x83\x75"
diff --git a/include/crypto/x509.h b/include/crypto/x509.h
index 243ea74..418c427 100644
--- a/include/crypto/x509.h
+++ b/include/crypto/x509.h
@@ -177,7 +177,7 @@ struct x509_st {
STACK_OF(DIST_POINT) *crldp;
STACK_OF(GENERAL_NAME) *altname;
NAME_CONSTRAINTS *nc;
-#ifndef OPENSSL_NO_RFC3779
+# ifndef OPENSSL_NO_RFC3779
STACK_OF(IPAddressFamily) *rfc3779_addr;
struct ASIdentifiers_st *rfc3779_asid;
# endif
@@ -185,6 +185,9 @@ struct x509_st {
X509_CERT_AUX *aux;
CRYPTO_RWLOCK *lock;
volatile int ex_cached;
+# ifndef OPENSSL_NO_SM2
+ ASN1_OCTET_STRING sm2_id;
+# endif
} /* X509 */ ;
/*
diff --git a/include/openssl/obj_mac.h b/include/openssl/obj_mac.h
index eb812ed..9b125c1 100644
--- a/include/openssl/obj_mac.h
+++ b/include/openssl/obj_mac.h
@@ -2,7 +2,7 @@
* WARNING: do not edit!
* Generated by crypto/objects/objects.pl
*
- * Copyright 2000-2021 The OpenSSL Project Authors. All Rights Reserved.
+ * Copyright 2000-2022 The OpenSSL Project Authors. All Rights Reserved.
* Licensed under the OpenSSL license (the "License"). You may not use
* this file except in compliance with the License. You can obtain a copy
* in the file LICENSE in the source distribution or at
@@ -1179,6 +1179,11 @@
#define NID_sm3WithRSAEncryption 1144
#define OBJ_sm3WithRSAEncryption OBJ_sm_scheme,504L
+#define SN_SM2_with_SM3 "SM2-SM3"
+#define LN_SM2_with_SM3 "SM2-with-SM3"
+#define NID_SM2_with_SM3 1195
+#define OBJ_SM2_with_SM3 OBJ_sm_scheme,501L
+
#define LN_hmacWithSHA224 "hmacWithSHA224"
#define NID_hmacWithSHA224 798
#define OBJ_hmacWithSHA224 OBJ_rsadsi,2L,8L
diff --git a/include/openssl/x509.h b/include/openssl/x509.h
index 3ff86ec..5f17057 100644
--- a/include/openssl/x509.h
+++ b/include/openssl/x509.h
@@ -573,6 +573,9 @@ void X509_get0_signature(const ASN1_BIT_STRING **psig,
const X509_ALGOR **palg, const X509 *x);
int X509_get_signature_nid(const X509 *x);
+void X509_set_sm2_id(X509 *x, ASN1_OCTET_STRING *sm2_id);
+ASN1_OCTET_STRING *X509_get0_sm2_id(X509 *x);
+
int X509_trusted(const X509 *x);
int X509_alias_set1(X509 *x, const unsigned char *name, int len);
int X509_keyid_set1(X509 *x, const unsigned char *id, int len);
diff --git a/include/openssl/x509err.h b/include/openssl/x509err.h
index cd08673..06d75f0 100644
--- a/include/openssl/x509err.h
+++ b/include/openssl/x509err.h
@@ -81,8 +81,10 @@ int ERR_load_X509_strings(void);
# define X509_F_X509_TO_X509_REQ 126
# define X509_F_X509_TRUST_ADD 133
# define X509_F_X509_TRUST_SET 141
+# define X509_F_X509_VERIFY 161
# define X509_F_X509_VERIFY_CERT 127
# define X509_F_X509_VERIFY_PARAM_NEW 159
+# define X509_F_X509_VERIFY_SM2 162
/*
* X509 reason codes.
diff --git a/util/libcrypto.num b/util/libcrypto.num
index 1566231..8635ac4 100644
--- a/util/libcrypto.num
+++ b/util/libcrypto.num
@@ -4626,3 +4626,5 @@ FIPS_drbg_get_strength 6379 1_1_0g EXIST::FUNCTION:
FIPS_rand_strength 6380 1_1_0g EXIST::FUNCTION:
FIPS_drbg_get_blocklength 6381 1_1_0g EXIST::FUNCTION:
FIPS_drbg_init 6382 1_1_0g EXIST::FUNCTION:
+X509_set_sm2_id 6383 1_1_1m EXIST::FUNCTION:
+X509_get0_sm2_id 6384 1_1_1m EXIST::FUNCTION:
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,127 @@
From 1d9e832e41858b13a96899d842afd183f1c66c48 Mon Sep 17 00:00:00 2001
From: Paul Yang <kaishen.yy@antfin.com>
Date: Tue, 30 Jul 2019 23:05:44 +0800
Subject: [PATCH 11/15] Support parsing of SM2 ID in hexdecimal
The current EVP_PEKY_ctrl for SM2 has no capability of parsing an ID
input in hexdecimal.
The newly added ctrl string is called: sm2_hex_id
Test cases and documentation are updated.
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/9584)
---
crypto/sm2/sm2_pmeth.c | 19 +++++++++++++++++++
doc/man1/pkeyutl.pod | 7 +++++++
include/openssl/ec.h | 1 -
test/recipes/25-test_req.t | 15 +++++++++++++--
4 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c
index 837bdc1..9551d70 100644
--- a/crypto/sm2/sm2_pmeth.c
+++ b/crypto/sm2/sm2_pmeth.c
@@ -232,6 +232,10 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
const char *type, const char *value)
{
+ uint8_t *hex_id;
+ long hex_len = 0;
+ int ret = 0;
+
if (strcmp(type, "ec_paramgen_curve") == 0) {
int nid = NID_undef;
@@ -255,6 +259,21 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
} else if (strcmp(type, "sm2_id") == 0) {
return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID,
(int)strlen(value), (void *)value);
+ } else if (strcmp(type, "sm2_hex_id") == 0) {
+ /*
+ * TODO(3.0): reconsider the name "sm2_hex_id", OR change
+ * OSSL_PARAM_construct_from_text() / OSSL_PARAM_allocate_from_text()
+ * to handle infix "_hex_"
+ */
+ hex_id = OPENSSL_hexstr2buf((const char *)value, &hex_len);
+ if (hex_id == NULL) {
+ SM2err(SM2_F_PKEY_SM2_CTRL_STR, ERR_R_PASSED_INVALID_ARGUMENT);
+ return 0;
+ }
+ ret = pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID, (int)hex_len,
+ (void *)hex_id);
+ OPENSSL_free(hex_id);
+ return ret;
}
return -2;
diff --git a/doc/man1/pkeyutl.pod b/doc/man1/pkeyutl.pod
index f0f80af..1a742ab 100644
--- a/doc/man1/pkeyutl.pod
+++ b/doc/man1/pkeyutl.pod
@@ -329,6 +329,13 @@ This sets the ID string used in SM2 sign or verify operations. While verifying
an SM2 signature, the ID string must be the same one used when signing the data.
Otherwise the verification will fail.
+=item B<sm2_hex_id:hex_string>
+
+This sets the ID string used in SM2 sign or verify operations. While verifying
+an SM2 signature, the ID string must be the same one used when signing the data.
+Otherwise the verification will fail. The ID string provided with this option
+should be a valid hexadecimal value.
+
=back
=head1 EXAMPLES
diff --git a/include/openssl/ec.h b/include/openssl/ec.h
index 24baf53..e8c8869 100644
--- a/include/openssl/ec.h
+++ b/include/openssl/ec.h
@@ -1444,7 +1444,6 @@ void EC_KEY_METHOD_get_verify(const EC_KEY_METHOD *meth,
# define EVP_PKEY_CTX_set1_id(ctx, id, id_len) \
EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
EVP_PKEY_CTRL_SET1_ID, (int)id_len, (void*)(id))
-
# define EVP_PKEY_CTX_get1_id(ctx, id) \
EVP_PKEY_CTX_ctrl(ctx, -1, -1, \
EVP_PKEY_CTRL_GET1_ID, 0, (void*)(id))
diff --git a/test/recipes/25-test_req.t b/test/recipes/25-test_req.t
index 8289959..d53e577 100644
--- a/test/recipes/25-test_req.t
+++ b/test/recipes/25-test_req.t
@@ -182,10 +182,10 @@ subtest "generating certificate requests" => sub {
};
subtest "generating SM2 certificate requests" => sub {
- plan tests => 2;
+ plan tests => 4;
SKIP: {
- skip "SM2 is not supported by this OpenSSL build", 2
+ skip "SM2 is not supported by this OpenSSL build", 4
if disabled("sm2");
ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"),
"-new", "-key", srctop_file("test", "certs", "sm2.key"),
@@ -197,6 +197,17 @@ subtest "generating SM2 certificate requests" => sub {
"-verify", "-in", "testreq.pem", "-noout",
"-sm2-id", "1234567812345678", "-sm3"])),
"Verifying signature on SM2 certificate request");
+
+ ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"),
+ "-new", "-key", srctop_file("test", "certs", "sm2.key"),
+ "-sigopt", "sm2_hex_id:DEADBEEF",
+ "-out", "testreq.pem", "-sm3"])),
+ "Generating SM2 certificate request with hex id");
+
+ ok(run(app(["openssl", "req", "-config", srctop_file("test", "test.cnf"),
+ "-verify", "-in", "testreq.pem", "-noout",
+ "-sm2-hex-id", "DEADBEEF", "-sm3"])),
+ "Verifying signature on SM2 certificate request");
}
};
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,482 @@
From b14bf717ccb166cce13173a817106effb02f6c2e Mon Sep 17 00:00:00 2001
From: Paul Yang <yang.yang@baishancloud.com>
Date: Wed, 16 Jan 2019 16:16:28 +0800
Subject: [PATCH 01/15] Support raw input data in apps/pkeyutl
Some signature algorithms require special treatment for digesting, such
as SM2. This patch adds the ability of handling raw input data in
apps/pkeyutl other than accepting only pre-hashed input data.
Beside, SM2 requries an ID string when signing or verifying a piece of data,
this patch also adds the ability for apps/pkeyutil to specify that ID
string.
Reviewed-by: Matt Caswell <matt@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/8186)
---
apps/pkeyutl.c | 168 +++++++++++++++++++++++++++++----
crypto/sm2/sm2_pmeth.c | 3 +
doc/man1/pkeyutl.pod | 45 +++++++++
test/certs/sm2.crt | 13 +++
test/certs/sm2.key | 5 +
test/recipes/20-test_pkeyutl.t | 43 +++++++++
6 files changed, 260 insertions(+), 17 deletions(-)
create mode 100644 test/certs/sm2.crt
create mode 100644 test/certs/sm2.key
create mode 100644 test/recipes/20-test_pkeyutl.t
diff --git a/apps/pkeyutl.c b/apps/pkeyutl.c
index 831e14d..bca0464 100644
--- a/apps/pkeyutl.c
+++ b/apps/pkeyutl.c
@@ -22,7 +22,7 @@
static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
const char *keyfile, int keyform, int key_type,
char *passinarg, int pkey_op, ENGINE *e,
- const int impl);
+ const int impl, EVP_PKEY **ppkey);
static int setup_peer(EVP_PKEY_CTX *ctx, int peerform, const char *file,
ENGINE *e);
@@ -31,6 +31,11 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
unsigned char *out, size_t *poutlen,
const unsigned char *in, size_t inlen);
+static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx,
+ const EVP_MD *md, EVP_PKEY *pkey, BIO *in,
+ unsigned char *sig, int siglen,
+ unsigned char **out, size_t *poutlen);
+
typedef enum OPTION_choice {
OPT_ERR = -1, OPT_EOF = 0, OPT_HELP,
OPT_ENGINE, OPT_ENGINE_IMPL, OPT_IN, OPT_OUT,
@@ -38,12 +43,15 @@ typedef enum OPTION_choice {
OPT_VERIFY, OPT_VERIFYRECOVER, OPT_REV, OPT_ENCRYPT, OPT_DECRYPT,
OPT_DERIVE, OPT_SIGFILE, OPT_INKEY, OPT_PEERKEY, OPT_PASSIN,
OPT_PEERFORM, OPT_KEYFORM, OPT_PKEYOPT, OPT_KDF, OPT_KDFLEN,
- OPT_R_ENUM
+ OPT_R_ENUM, OPT_RAWIN, OPT_DIGEST
} OPTION_CHOICE;
const OPTIONS pkeyutl_options[] = {
{"help", OPT_HELP, '-', "Display this summary"},
{"in", OPT_IN, '<', "Input file - default stdin"},
+ {"rawin", OPT_RAWIN, '-', "Indicate the input data is in raw form"},
+ {"digest", OPT_DIGEST, 's',
+ "Specify the digest algorithm when signing the raw input data"},
{"out", OPT_OUT, '>', "Output file - default stdout"},
{"pubin", OPT_PUBIN, '-', "Input is a public key"},
{"certin", OPT_CERTIN, '-', "Input is a cert with a public key"},
@@ -80,6 +88,7 @@ int pkeyutl_main(int argc, char **argv)
BIO *in = NULL, *out = NULL;
ENGINE *e = NULL;
EVP_PKEY_CTX *ctx = NULL;
+ EVP_PKEY *pkey = NULL;
char *infile = NULL, *outfile = NULL, *sigfile = NULL, *passinarg = NULL;
char hexdump = 0, asn1parse = 0, rev = 0, *prog;
unsigned char *buf_in = NULL, *buf_out = NULL, *sig = NULL;
@@ -94,6 +103,8 @@ int pkeyutl_main(int argc, char **argv)
const char *kdfalg = NULL;
int kdflen = 0;
STACK_OF(OPENSSL_STRING) *pkeyopts = NULL;
+ int rawin = 0;
+ const EVP_MD *md = NULL;
prog = opt_init(argc, argv, pkeyutl_options);
while ((o = opt_next()) != OPT_EOF) {
@@ -192,12 +203,39 @@ int pkeyutl_main(int argc, char **argv)
goto end;
}
break;
+ case OPT_RAWIN:
+ rawin = 1;
+ break;
+ case OPT_DIGEST:
+ if (!opt_md(opt_arg(), &md))
+ goto end;
+ break;
}
}
argc = opt_num_rest();
if (argc != 0)
goto opthelp;
+ if (rawin && pkey_op != EVP_PKEY_OP_SIGN && pkey_op != EVP_PKEY_OP_VERIFY) {
+ BIO_printf(bio_err,
+ "%s: -rawin can only be used with -sign or -verify\n",
+ prog);
+ goto opthelp;
+ }
+
+ if (md != NULL && !rawin) {
+ BIO_printf(bio_err,
+ "%s: -digest can only be used with -rawin\n",
+ prog);
+ goto opthelp;
+ }
+
+ if (rawin && rev) {
+ BIO_printf(bio_err, "%s: -rev cannot be used with raw input\n",
+ prog);
+ goto opthelp;
+ }
+
if (kdfalg != NULL) {
if (kdflen == 0) {
BIO_printf(bio_err,
@@ -214,7 +252,7 @@ int pkeyutl_main(int argc, char **argv)
goto opthelp;
}
ctx = init_ctx(kdfalg, &keysize, inkey, keyform, key_type,
- passinarg, pkey_op, e, engine_impl);
+ passinarg, pkey_op, e, engine_impl, &pkey);
if (ctx == NULL) {
BIO_printf(bio_err, "%s: Error initializing context\n", prog);
ERR_print_errors(bio_err);
@@ -277,7 +315,8 @@ int pkeyutl_main(int argc, char **argv)
}
}
- if (in != NULL) {
+ /* Raw input data is handled elsewhere */
+ if (in != NULL && !rawin) {
/* Read the input data */
buf_inlen = bio_to_mem(&buf_in, keysize * 10, in);
if (buf_inlen < 0) {
@@ -296,8 +335,9 @@ int pkeyutl_main(int argc, char **argv)
}
}
- /* Sanity check the input */
- if (buf_inlen > EVP_MAX_MD_SIZE
+ /* Sanity check the input if the input is not raw */
+ if (!rawin
+ && buf_inlen > EVP_MAX_MD_SIZE
&& (pkey_op == EVP_PKEY_OP_SIGN
|| pkey_op == EVP_PKEY_OP_VERIFY)) {
BIO_printf(bio_err,
@@ -306,8 +346,13 @@ int pkeyutl_main(int argc, char **argv)
}
if (pkey_op == EVP_PKEY_OP_VERIFY) {
- rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
- buf_in, (size_t)buf_inlen);
+ if (rawin) {
+ rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, sig, siglen,
+ NULL, 0);
+ } else {
+ rv = EVP_PKEY_verify(ctx, sig, (size_t)siglen,
+ buf_in, (size_t)buf_inlen);
+ }
if (rv == 1) {
BIO_puts(out, "Signature Verified Successfully\n");
ret = 0;
@@ -320,14 +365,20 @@ int pkeyutl_main(int argc, char **argv)
buf_outlen = kdflen;
rv = 1;
} else {
- rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
- buf_in, (size_t)buf_inlen);
- }
- if (rv > 0 && buf_outlen != 0) {
- buf_out = app_malloc(buf_outlen, "buffer output");
- rv = do_keyop(ctx, pkey_op,
- buf_out, (size_t *)&buf_outlen,
- buf_in, (size_t)buf_inlen);
+ if (rawin) {
+ /* rawin allocates the buffer in do_raw_keyop() */
+ rv = do_raw_keyop(pkey_op, ctx, md, pkey, in, NULL, 0,
+ &buf_out, (size_t *)&buf_outlen);
+ } else {
+ rv = do_keyop(ctx, pkey_op, NULL, (size_t *)&buf_outlen,
+ buf_in, (size_t)buf_inlen);
+ if (rv > 0 && buf_outlen != 0) {
+ buf_out = app_malloc(buf_outlen, "buffer output");
+ rv = do_keyop(ctx, pkey_op,
+ buf_out, (size_t *)&buf_outlen,
+ buf_in, (size_t)buf_inlen);
+ }
+ }
}
if (rv <= 0) {
if (pkey_op != EVP_PKEY_OP_DERIVE) {
@@ -364,7 +415,7 @@ int pkeyutl_main(int argc, char **argv)
static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
const char *keyfile, int keyform, int key_type,
char *passinarg, int pkey_op, ENGINE *e,
- const int engine_impl)
+ const int engine_impl, EVP_PKEY **ppkey)
{
EVP_PKEY *pkey = NULL;
EVP_PKEY_CTX *ctx = NULL;
@@ -422,10 +473,25 @@ static EVP_PKEY_CTX *init_ctx(const char *kdfalg, int *pkeysize,
}
ctx = EVP_PKEY_CTX_new_id(kdfnid, impl);
} else {
+ EC_KEY *eckey = NULL;
+ const EC_GROUP *group = NULL;
+ int nid;
+
if (pkey == NULL)
goto end;
+ /* SM2 needs a special treatment */
+ if (EVP_PKEY_id(pkey) == EVP_PKEY_EC) {
+ if ((eckey = EVP_PKEY_get0_EC_KEY(pkey)) == NULL
+ || (group = EC_KEY_get0_group(eckey)) == NULL
+ || (nid = EC_GROUP_get_curve_name(group)) == 0)
+ goto end;
+ if (nid == NID_sm2)
+ EVP_PKEY_set_alias_type(pkey, EVP_PKEY_SM2);
+ }
*pkeysize = EVP_PKEY_size(pkey);
ctx = EVP_PKEY_CTX_new(pkey, impl);
+ if (ppkey != NULL)
+ *ppkey = pkey;
EVP_PKEY_free(pkey);
}
@@ -522,3 +588,71 @@ static int do_keyop(EVP_PKEY_CTX *ctx, int pkey_op,
}
return rv;
}
+
+#define TBUF_MAXSIZE 2048
+
+static int do_raw_keyop(int pkey_op, EVP_PKEY_CTX *ctx,
+ const EVP_MD *md, EVP_PKEY *pkey, BIO *in,
+ unsigned char *sig, int siglen,
+ unsigned char **out, size_t *poutlen)
+{
+ int rv = 0;
+ EVP_MD_CTX *mctx = NULL;
+ unsigned char tbuf[TBUF_MAXSIZE];
+ int tbuf_len = 0;
+
+ if ((mctx = EVP_MD_CTX_new()) == NULL) {
+ BIO_printf(bio_err, "Error: out of memory\n");
+ return rv;
+ }
+ EVP_MD_CTX_set_pkey_ctx(mctx, ctx);
+
+ switch(pkey_op) {
+ case EVP_PKEY_OP_VERIFY:
+ if (EVP_DigestVerifyInit(mctx, NULL, md, NULL, pkey) != 1)
+ goto end;
+ for (;;) {
+ tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE);
+ if (tbuf_len == 0)
+ break;
+ if (tbuf_len < 0) {
+ BIO_printf(bio_err, "Error reading raw input data\n");
+ goto end;
+ }
+ rv = EVP_DigestVerifyUpdate(mctx, tbuf, (size_t)tbuf_len);
+ if (rv != 1) {
+ BIO_printf(bio_err, "Error verifying raw input data\n");
+ goto end;
+ }
+ }
+ rv = EVP_DigestVerifyFinal(mctx, sig, (size_t)siglen);
+ break;
+ case EVP_PKEY_OP_SIGN:
+ if (EVP_DigestSignInit(mctx, NULL, md, NULL, pkey) != 1)
+ goto end;
+ for (;;) {
+ tbuf_len = BIO_read(in, tbuf, TBUF_MAXSIZE);
+ if (tbuf_len == 0)
+ break;
+ if (tbuf_len < 0) {
+ BIO_printf(bio_err, "Error reading raw input data\n");
+ goto end;
+ }
+ rv = EVP_DigestSignUpdate(mctx, tbuf, (size_t)tbuf_len);
+ if (rv != 1) {
+ BIO_printf(bio_err, "Error signing raw input data\n");
+ goto end;
+ }
+ }
+ rv = EVP_DigestSignFinal(mctx, NULL, poutlen);
+ if (rv == 1 && out != NULL) {
+ *out = app_malloc(*poutlen, "buffer output");
+ rv = EVP_DigestSignFinal(mctx, *out, poutlen);
+ }
+ break;
+ }
+
+ end:
+ EVP_MD_CTX_free(mctx);
+ return rv;
+}
diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c
index 0e722b9..837bdc1 100644
--- a/crypto/sm2/sm2_pmeth.c
+++ b/crypto/sm2/sm2_pmeth.c
@@ -252,6 +252,9 @@ static int pkey_sm2_ctrl_str(EVP_PKEY_CTX *ctx,
else
return -2;
return EVP_PKEY_CTX_set_ec_param_enc(ctx, param_enc);
+ } else if (strcmp(type, "sm2_id") == 0) {
+ return pkey_sm2_ctrl(ctx, EVP_PKEY_CTRL_SET1_ID,
+ (int)strlen(value), (void *)value);
}
return -2;
diff --git a/doc/man1/pkeyutl.pod b/doc/man1/pkeyutl.pod
index f6fd48d..f0f80af 100644
--- a/doc/man1/pkeyutl.pod
+++ b/doc/man1/pkeyutl.pod
@@ -10,6 +10,8 @@ pkeyutl - public key algorithm utility
B<openssl> B<pkeyutl>
[B<-help>]
[B<-in file>]
+[B<-rawin>]
+[B<-digest algorithm>]
[B<-out file>]
[B<-sigfile file>]
[B<-inkey file>]
@@ -54,6 +56,23 @@ Print out a usage message.
This specifies the input filename to read data from or standard input
if this option is not specified.
+=item B<-rawin>
+
+This indicates that the input data is raw data, which is not hashed by any
+message digest algorithm. The user can specify a digest algorithm by using
+the B<-digest> option. This option can only be used with B<-sign> and
+B<-verify>.
+
+=item B<-digest algorithm>
+
+This specifies the digest algorithm which is used to hash the input data before
+signing or verifying it with the input key. This option could be omitted if the
+signature algorithm does not require one (for instance, EdDSA). If this option
+is omitted but the signature algorithm requires one, a default value will be
+used. For signature algorithms like RSA, DSA and ECDSA, SHA-256 will be the
+default digest algorithm. For SM2, it will be SM3. If this option is present,
+then the B<-rawin> option must be also specified to B<pkeyutl>.
+
=item B<-out filename>
Specifies the output filename to write to or standard output by
@@ -296,6 +315,22 @@ the B<-pkeyopt> B<digest> option.
The X25519 and X448 algorithms support key derivation only. Currently there are
no additional options.
+=head1 SM2
+
+The SM2 algorithm supports sign, verify, encrypt and decrypt operations. For
+the sign and verify operations, SM2 requires an ID string to be passed in. The
+following B<pkeyopt> value is supported:
+
+=over 4
+
+=item B<sm2_id:string>
+
+This sets the ID string used in SM2 sign or verify operations. While verifying
+an SM2 signature, the ID string must be the same one used when signing the data.
+Otherwise the verification will fail.
+
+=back
+
=head1 EXAMPLES
Sign some data using a private key:
@@ -329,6 +364,16 @@ Decrypt some data using a private key with OAEP padding using SHA256:
openssl pkeyutl -decrypt -in file -inkey key.pem -out secret \
-pkeyopt rsa_padding_mode:oaep -pkeyopt rsa_oaep_md:sha256
+Sign some data using an L<SM2(7)> private key and a specific ID:
+
+ openssl pkeyutl -sign -in file -inkey sm2.key -out sig -rawin -digest sm3 \
+ -pkeyopt sm2_id:someid
+
+Verify some data using an L<SM2(7)> certificate and a specific ID:
+
+ openssl pkeyutl -verify -certin -in file -inkey sm2.cert -sigfile sig \
+ -rawin -digest sm3 -pkeyopt sm2_id:someid
+
=head1 SEE ALSO
L<genpkey(1)>, L<pkey(1)>, L<rsautl(1)>
diff --git a/test/certs/sm2.crt b/test/certs/sm2.crt
new file mode 100644
index 0000000..189abb1
--- /dev/null
+++ b/test/certs/sm2.crt
@@ -0,0 +1,13 @@
+-----BEGIN CERTIFICATE-----
+MIIB6DCCAY6gAwIBAgIJAKH2BR6ITHZeMAoGCCqBHM9VAYN1MGgxCzAJBgNVBAYT
+AkNOMQswCQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRl
+c3QgT3JnMRAwDgYDVQQLDAdUZXN0IE9VMRQwEgYDVQQDDAtUZXN0IFNNMiBDQTAe
+Fw0xOTAyMTkwNzA1NDhaFw0yMzAzMzAwNzA1NDhaMG8xCzAJBgNVBAYTAkNOMQsw
+CQYDVQQIDAJMTjERMA8GA1UEBwwIU2hlbnlhbmcxETAPBgNVBAoMCFRlc3QgT3Jn
+MRAwDgYDVQQLDAdUZXN0IE9VMRswGQYDVQQDDBJUZXN0IFNNMiBTaWduIENlcnQw
+WTATBgcqhkjOPQIBBggqgRzPVQGCLQNCAAQwqeNkWp7fiu1KZnuDkAucpM8piEzE
+TL1ymrcrOBvv8mhNNkeb20asbWgFQI2zOrSM99/sXGn9rM2/usM/MlcaoxowGDAJ
+BgNVHRMEAjAAMAsGA1UdDwQEAwIGwDAKBggqgRzPVQGDdQNIADBFAiEA9edBnAqT
+TNuGIUIvXsj6/nP+AzXA9HGtAIY4nrqW8LkCIHyZzhRTlxYtgfqkDl0OK5QQRCZH
+OZOfmtx613VyzXwc
+-----END CERTIFICATE-----
diff --git a/test/certs/sm2.key b/test/certs/sm2.key
new file mode 100644
index 0000000..1efd364
--- /dev/null
+++ b/test/certs/sm2.key
@@ -0,0 +1,5 @@
+-----BEGIN PRIVATE KEY-----
+MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQgSKhk+4xGyDI+IS2H
+WVfFPDxh1qv5+wtrddaIsGNXGZihRANCAAQwqeNkWp7fiu1KZnuDkAucpM8piEzE
+TL1ymrcrOBvv8mhNNkeb20asbWgFQI2zOrSM99/sXGn9rM2/usM/Mlca
+-----END PRIVATE KEY-----
diff --git a/test/recipes/20-test_pkeyutl.t b/test/recipes/20-test_pkeyutl.t
new file mode 100644
index 0000000..a051138
--- /dev/null
+++ b/test/recipes/20-test_pkeyutl.t
@@ -0,0 +1,43 @@
+#! /usr/bin/env perl
+# Copyright 2018 The OpenSSL Project Authors. All Rights Reserved.
+#
+# Licensed under the Apache License 2.0 (the "License"). You may not use
+# this file except in compliance with the License. You can obtain a copy
+# in the file LICENSE in the source distribution or at
+# https://www.openssl.org/source/license.html
+
+use strict;
+use warnings;
+
+use File::Spec;
+use OpenSSL::Test qw/:DEFAULT srctop_file/;
+use OpenSSL::Test::Utils;
+
+setup("test_pkeyutl");
+
+plan tests => 2;
+
+sub sign
+{
+ # Utilize the sm2.crt as the TBS file
+ return run(app(([ 'openssl', 'pkeyutl', '-sign',
+ '-in', srctop_file('test', 'certs', 'sm2.crt'),
+ '-inkey', srctop_file('test', 'certs', 'sm2.key'),
+ '-out', 'signature.sm2', '-rawin',
+ '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid'])));
+}
+
+sub verify
+{
+ # Utilize the sm2.crt as the TBS file
+ return run(app(([ 'openssl', 'pkeyutl', '-verify', '-certin',
+ '-in', srctop_file('test', 'certs', 'sm2.crt'),
+ '-inkey', srctop_file('test', 'certs', 'sm2.crt'),
+ '-sigfile', 'signature.sm2', '-rawin',
+ '-digest', 'sm3', '-pkeyopt', 'sm2_id:someid'])));
+}
+
+ok(sign, "Sign a piece of data using SM2");
+ok(verify, "Verify an SM2 signature against a piece of data");
+
+unlink 'signature.sm2';
--
2.20.1 (Apple Git-117)

View File

@ -0,0 +1,58 @@
From 3ef5c3034e5c545f34d6929568f3f2b10ac4bdf0 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Mon, 28 Feb 2022 18:26:35 +0100
Subject: [PATCH] Add a negative testcase for BN_mod_sqrt
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
---
test/bntest.c | 11 ++++++++++-
test/recipes/10-test_bn_data/bnmod.txt | 12 ++++++++++++
2 files changed, 22 insertions(+), 1 deletion(-)
diff --git a/test/bntest.c b/test/bntest.c
index 390dd80073..1cab660bca 100644
--- a/test/bntest.c
+++ b/test/bntest.c
@@ -1729,8 +1729,17 @@ static int file_modsqrt(STANZA *s)
|| !TEST_ptr(ret2 = BN_new()))
goto err;
+ if (BN_is_negative(mod_sqrt)) {
+ /* A negative testcase */
+ if (!TEST_ptr_null(BN_mod_sqrt(ret, a, p, ctx)))
+ goto err;
+
+ st = 1;
+ goto err;
+ }
+
/* There are two possible answers. */
- if (!TEST_true(BN_mod_sqrt(ret, a, p, ctx))
+ if (!TEST_ptr(BN_mod_sqrt(ret, a, p, ctx))
|| !TEST_true(BN_sub(ret2, p, ret)))
goto err;
diff --git a/test/recipes/10-test_bn_data/bnmod.txt b/test/recipes/10-test_bn_data/bnmod.txt
index 5ea4d031f2..e28cc6bfb0 100644
--- a/test/recipes/10-test_bn_data/bnmod.txt
+++ b/test/recipes/10-test_bn_data/bnmod.txt
@@ -2799,3 +2799,15 @@ P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f
ModSqrt = a1d52989f12f204d3d2167d9b1e6c8a6174c0c786a979a5952383b7b8bd186
A = 2eee37cf06228a387788188e650bc6d8a2ff402931443f69156a29155eca07dcb45f3aac238d92943c0c25c896098716baa433f25bd696a142f5a69d5d937e81
P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f
+
+# Negative testcases for BN_mod_sqrt()
+
+# This one triggers an infinite loop with unfixed implementation
+# It should just fail.
+ModSqrt = -1
+A = 20a7ee
+P = 460201
+
+ModSqrt = -1
+A = 65bebdb00a96fc814ec44b81f98b59fba3c30203928fa5214c51e0a97091645280c947b005847f239758482b9bfc45b066fde340d1fe32fc9c1bf02e1b2d0ed
+P = 9df9d6cc20b8540411af4e5357ef2b0353cb1f2ab5ffc3e246b41c32f71e951f
--
2.27.0

View File

@ -0,0 +1,69 @@
From 3118eb64934499d93db3230748a452351d1d9a65 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Mon, 28 Feb 2022 18:26:21 +0100
Subject: [PATCH] Fix possible infinite loop in BN_mod_sqrt()
The calculation in some cases does not finish for non-prime p.
This fixes CVE-2022-0778.
Based on patch by David Benjamin <davidben@google.com>.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
---
crypto/bn/bn_sqrt.c | 30 ++++++++++++++++++------------
1 file changed, 18 insertions(+), 12 deletions(-)
diff --git a/crypto/bn/bn_sqrt.c b/crypto/bn/bn_sqrt.c
index 1723d5ded5..53b0f55985 100644
--- a/crypto/bn/bn_sqrt.c
+++ b/crypto/bn/bn_sqrt.c
@@ -14,7 +14,8 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
/*
* Returns 'ret' such that ret^2 == a (mod p), using the Tonelli/Shanks
* algorithm (cf. Henri Cohen, "A Course in Algebraic Computational Number
- * Theory", algorithm 1.5.1). 'p' must be prime!
+ * Theory", algorithm 1.5.1). 'p' must be prime, otherwise an error or
+ * an incorrect "result" will be returned.
*/
{
BIGNUM *ret = in;
@@ -301,18 +302,23 @@ BIGNUM *BN_mod_sqrt(BIGNUM *in, const BIGNUM *a, const BIGNUM *p, BN_CTX *ctx)
goto vrfy;
}
- /* find smallest i such that b^(2^i) = 1 */
- i = 1;
- if (!BN_mod_sqr(t, b, p, ctx))
- goto end;
- while (!BN_is_one(t)) {
- i++;
- if (i == e) {
- BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
- goto end;
+ /* Find the smallest i, 0 < i < e, such that b^(2^i) = 1. */
+ for (i = 1; i < e; i++) {
+ if (i == 1) {
+ if (!BN_mod_sqr(t, b, p, ctx))
+ goto end;
+
+ } else {
+ if (!BN_mod_mul(t, t, t, p, ctx))
+ goto end;
}
- if (!BN_mod_mul(t, t, t, p, ctx))
- goto end;
+ if (BN_is_one(t))
+ break;
+ }
+ /* If not found, a is not a square or p is not prime. */
+ if (i >= e) {
+ BNerr(BN_F_BN_MOD_SQRT, BN_R_NOT_A_SQUARE);
+ goto end;
}
/* t := y^2^(e - i - 1) */
--
2.27.0

View File

@ -0,0 +1,76 @@
From e5fd1728ef4c7a5bf7c7a7163ca60370460a6e23 Mon Sep 17 00:00:00 2001
From: Tomas Mraz <tomas@openssl.org>
Date: Tue, 26 Apr 2022 12:40:24 +0200
Subject: [PATCH] c_rehash: Do not use shell to invoke openssl
Except on VMS where it is safe.
This fixes CVE-2022-1292.
Reviewed-by: Matthias St. Pierre <Matthias.St.Pierre@ncp-e.com>
Reviewed-by: Matt Caswell <matt@openssl.org>
---
tools/c_rehash.in | 29 +++++++++++++++++++++++++----
1 file changed, 25 insertions(+), 4 deletions(-)
diff --git a/tools/c_rehash.in b/tools/c_rehash.in
index fa7c6c9..83c1cc8 100644
--- a/tools/c_rehash.in
+++ b/tools/c_rehash.in
@@ -152,6 +152,23 @@ sub check_file {
return ($is_cert, $is_crl);
}
+sub compute_hash {
+ my $fh;
+ if ( $^O eq "VMS" ) {
+ # VMS uses the open through shell
+ # The file names are safe there and list form is unsupported
+ if (!open($fh, "-|", join(' ', @_))) {
+ print STDERR "Cannot compute hash on '$fname'\n";
+ return;
+ }
+ } else {
+ if (!open($fh, "-|", @_)) {
+ print STDERR "Cannot compute hash on '$fname'\n";
+ return;
+ }
+ }
+ return (<$fh>, <$fh>);
+}
# Link a certificate to its subject name hash value, each hash is of
# the form <hash>.<n> where n is an integer. If the hash value already exists
@@ -161,10 +178,12 @@ sub check_file {
sub link_hash_cert {
my $fname = $_[0];
- $fname =~ s/\"/\\\"/g;
- my ($hash, $fprint) = `"$openssl" x509 $x509hash -fingerprint -noout -in "$fname"`;
+ my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash,
+ "-fingerprint", "-noout",
+ "-in", $fname);
chomp $hash;
chomp $fprint;
+ return if !$hash;
$fprint =~ s/^.*=//;
$fprint =~ tr/://d;
my $suffix = 0;
@@ -202,10 +221,12 @@ sub link_hash_cert {
sub link_hash_crl {
my $fname = $_[0];
- $fname =~ s/'/'\\''/g;
- my ($hash, $fprint) = `"$openssl" crl $crlhash -fingerprint -noout -in '$fname'`;
+ my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash,
+ "-fingerprint", "-noout",
+ "-in", $fname);
chomp $hash;
chomp $fprint;
+ return if !$hash;
$fprint =~ s/^.*=//;
$fprint =~ tr/://d;
my $suffix = 0;
--
1.8.3.1

View File

@ -0,0 +1,257 @@
From 9639817dac8bbbaa64d09efad7464ccc405527c7 Mon Sep 17 00:00:00 2001
From: Daniel Fiala <daniel@openssl.org>
Date: Sun, 29 May 2022 20:11:24 +0200
Subject: [PATCH] Fix file operations in c_rehash.
CVE-2022-2068
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
---
tools/c_rehash.in | 216 +++++++++++++++++++++++++++---------------------------
1 file changed, 107 insertions(+), 109 deletions(-)
diff --git a/tools/c_rehash.in b/tools/c_rehash.in
index cfd18f5..9d2a6f6 100644
--- a/tools/c_rehash.in
+++ b/tools/c_rehash.in
@@ -104,52 +104,78 @@ foreach (@dirlist) {
}
exit($errorcount);
+sub copy_file {
+ my ($src_fname, $dst_fname) = @_;
+
+ if (open(my $in, "<", $src_fname)) {
+ if (open(my $out, ">", $dst_fname)) {
+ print $out $_ while (<$in>);
+ close $out;
+ } else {
+ warn "Cannot open $dst_fname for write, $!";
+ }
+ close $in;
+ } else {
+ warn "Cannot open $src_fname for read, $!";
+ }
+}
+
sub hash_dir {
- my %hashlist;
- print "Doing $_[0]\n";
- chdir $_[0];
- opendir(DIR, ".");
- my @flist = sort readdir(DIR);
- closedir DIR;
- if ( $removelinks ) {
- # Delete any existing symbolic links
- foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
- if (-l $_) {
- print "unlink $_" if $verbose;
- unlink $_ || warn "Can't unlink $_, $!\n";
- }
- }
- }
- FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) {
- # Check to see if certificates and/or CRLs present.
- my ($cert, $crl) = check_file($fname);
- if (!$cert && !$crl) {
- print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
- next;
- }
- link_hash_cert($fname) if ($cert);
- link_hash_crl($fname) if ($crl);
- }
+ my $dir = shift;
+ my %hashlist;
+
+ print "Doing $dir\n";
+
+ if (!chdir $dir) {
+ print STDERR "WARNING: Cannot chdir to '$dir', $!\n";
+ return;
+ }
+
+ opendir(DIR, ".") || print STDERR "WARNING: Cannot opendir '.', $!\n";
+ my @flist = sort readdir(DIR);
+ closedir DIR;
+ if ( $removelinks ) {
+ # Delete any existing symbolic links
+ foreach (grep {/^[\da-f]+\.r{0,1}\d+$/} @flist) {
+ if (-l $_) {
+ print "unlink $_\n" if $verbose;
+ unlink $_ || warn "Can't unlink $_, $!\n";
+ }
+ }
+ }
+ FILE: foreach $fname (grep {/\.(pem)|(crt)|(cer)|(crl)$/} @flist) {
+ # Check to see if certificates and/or CRLs present.
+ my ($cert, $crl) = check_file($fname);
+ if (!$cert && !$crl) {
+ print STDERR "WARNING: $fname does not contain a certificate or CRL: skipping\n";
+ next;
+ }
+ link_hash_cert($fname) if ($cert);
+ link_hash_crl($fname) if ($crl);
+ }
+
+ chdir $pwd;
}
sub check_file {
- my ($is_cert, $is_crl) = (0,0);
- my $fname = $_[0];
- open IN, $fname;
- while(<IN>) {
- if (/^-----BEGIN (.*)-----/) {
- my $hdr = $1;
- if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
- $is_cert = 1;
- last if ($is_crl);
- } elsif ($hdr eq "X509 CRL") {
- $is_crl = 1;
- last if ($is_cert);
- }
- }
- }
- close IN;
- return ($is_cert, $is_crl);
+ my ($is_cert, $is_crl) = (0,0);
+ my $fname = $_[0];
+
+ open(my $in, "<", $fname);
+ while(<$in>) {
+ if (/^-----BEGIN (.*)-----/) {
+ my $hdr = $1;
+ if ($hdr =~ /^(X509 |TRUSTED |)CERTIFICATE$/) {
+ $is_cert = 1;
+ last if ($is_crl);
+ } elsif ($hdr eq "X509 CRL") {
+ $is_crl = 1;
+ last if ($is_cert);
+ }
+ }
+ }
+ close $in;
+ return ($is_cert, $is_crl);
}
sub compute_hash {
@@ -177,76 +203,48 @@ sub compute_hash {
# certificate fingerprints
sub link_hash_cert {
- my $fname = $_[0];
- my ($hash, $fprint) = compute_hash($openssl, "x509", $x509hash,
- "-fingerprint", "-noout",
- "-in", $fname);
- chomp $hash;
- chomp $fprint;
- return if !$hash;
- $fprint =~ s/^.*=//;
- $fprint =~ tr/://d;
- my $suffix = 0;
- # Search for an unused hash filename
- while(exists $hashlist{"$hash.$suffix"}) {
- # Hash matches: if fingerprint matches its a duplicate cert
- if ($hashlist{"$hash.$suffix"} eq $fprint) {
- print STDERR "WARNING: Skipping duplicate certificate $fname\n";
- return;
- }
- $suffix++;
- }
- $hash .= ".$suffix";
- if ($symlink_exists) {
- print "link $fname -> $hash\n" if $verbose;
- symlink $fname, $hash || warn "Can't symlink, $!";
- } else {
- print "copy $fname -> $hash\n" if $verbose;
- if (open($in, "<", $fname)) {
- if (open($out,">", $hash)) {
- print $out $_ while (<$in>);
- close $out;
- } else {
- warn "can't open $hash for write, $!";
- }
- close $in;
- } else {
- warn "can't open $fname for read, $!";
- }
- }
- $hashlist{$hash} = $fprint;
+ link_hash($_[0], 'cert');
}
# Same as above except for a CRL. CRL links are of the form <hash>.r<n>
sub link_hash_crl {
- my $fname = $_[0];
- my ($hash, $fprint) = compute_hash($openssl, "crl", $crlhash,
- "-fingerprint", "-noout",
- "-in", $fname);
- chomp $hash;
- chomp $fprint;
- return if !$hash;
- $fprint =~ s/^.*=//;
- $fprint =~ tr/://d;
- my $suffix = 0;
- # Search for an unused hash filename
- while(exists $hashlist{"$hash.r$suffix"}) {
- # Hash matches: if fingerprint matches its a duplicate cert
- if ($hashlist{"$hash.r$suffix"} eq $fprint) {
- print STDERR "WARNING: Skipping duplicate CRL $fname\n";
- return;
- }
- $suffix++;
- }
- $hash .= ".r$suffix";
- if ($symlink_exists) {
- print "link $fname -> $hash\n" if $verbose;
- symlink $fname, $hash || warn "Can't symlink, $!";
- } else {
- print "cp $fname -> $hash\n" if $verbose;
- system ("cp", $fname, $hash);
- warn "Can't copy, $!" if ($? >> 8) != 0;
- }
- $hashlist{$hash} = $fprint;
+ link_hash($_[0], 'crl');
+}
+
+sub link_hash {
+ my ($fname, $type) = @_;
+ my $is_cert = $type eq 'cert';
+
+ my ($hash, $fprint) = compute_hash($openssl,
+ $is_cert ? "x509" : "crl",
+ $is_cert ? $x509hash : $crlhash,
+ "-fingerprint", "-noout",
+ "-in", $fname);
+ chomp $hash;
+ chomp $fprint;
+ return if !$hash;
+ $fprint =~ s/^.*=//;
+ $fprint =~ tr/://d;
+ my $suffix = 0;
+ # Search for an unused hash filename
+ my $crlmark = $is_cert ? "" : "r";
+ while(exists $hashlist{"$hash.$crlmark$suffix"}) {
+ # Hash matches: if fingerprint matches its a duplicate cert
+ if ($hashlist{"$hash.$crlmark$suffix"} eq $fprint) {
+ my $what = $is_cert ? 'certificate' : 'CRL';
+ print STDERR "WARNING: Skipping duplicate $what $fname\n";
+ return;
+ }
+ $suffix++;
+ }
+ $hash .= ".$crlmark$suffix";
+ if ($symlink_exists) {
+ print "link $fname -> $hash\n" if $verbose;
+ symlink $fname, $hash || warn "Can't symlink, $!";
+ } else {
+ print "copy $fname -> $hash\n" if $verbose;
+ copy_file($fname, $hash);
+ }
+ $hashlist{$hash} = $fprint;
}
--
1.8.3.1

View File

@ -0,0 +1,73 @@
From 919925673d6c9cfed3c1085497f5dfbbed5fc431 Mon Sep 17 00:00:00 2001
From: Alex Chernyakhovsky <achernya@google.com>
Date: Thu, 16 Jun 2022 12:00:22 +1000
Subject: [PATCH] Fix AES OCB encrypt/decrypt for x86 AES-NI
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
aesni_ocb_encrypt and aesni_ocb_decrypt operate by having a fast-path
that performs operations on 6 16-byte blocks concurrently (the
"grandloop") and then proceeds to handle the "short" tail (which can
be anywhere from 0 to 5 blocks) that remain.
As part of initialization, the assembly initializes $len to the true
length, less 96 bytes and converts it to a pointer so that the $inp
can be compared to it. Each iteration of "grandloop" checks to see if
there's a full 96-byte chunk to process, and if so, continues. Once
this has been exhausted, it falls through to "short", which handles
the remaining zero to five blocks.
Unfortunately, the jump at the end of "grandloop" had a fencepost
error, doing a `jb` ("jump below") rather than `jbe` (jump below or
equal). This should be `jbe`, as $inp is pointing to the *end* of the
chunk currently being handled. If $inp == $len, that means that
there's a whole 96-byte chunk waiting to be handled. If $inp > $len,
then there's 5 or fewer 16-byte blocks left to be handled, and the
fall-through is intended.
The net effect of `jb` instead of `jbe` is that the last 16-byte block
of the last 96-byte chunk was completely omitted. The contents of
`out` in this position were never written to. Additionally, since
those bytes were never processed, the authentication tag generated is
also incorrect.
The same fencepost error, and identical logic, exists in both
aesni_ocb_encrypt and aesni_ocb_decrypt.
This addresses CVE-2022-2097.
Co-authored-by: Alejandro Sedeño <asedeno@google.com>
Co-authored-by: David Benjamin <davidben@google.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
crypto/aes/asm/aesni-x86.pl | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/crypto/aes/asm/aesni-x86.pl b/crypto/aes/asm/aesni-x86.pl
index fe2b265..812758e 100644
--- a/crypto/aes/asm/aesni-x86.pl
+++ b/crypto/aes/asm/aesni-x86.pl
@@ -2027,7 +2027,7 @@ my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out);
&movdqu (&QWP(-16*2,$out,$inp),$inout4);
&movdqu (&QWP(-16*1,$out,$inp),$inout5);
&cmp ($inp,$len); # done yet?
- &jb (&label("grandloop"));
+ &jbe (&label("grandloop"));
&set_label("short");
&add ($len,16*6);
@@ -2453,7 +2453,7 @@ my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out);
&pxor ($rndkey1,$inout5);
&movdqu (&QWP(-16*1,$out,$inp),$inout5);
&cmp ($inp,$len); # done yet?
- &jb (&label("grandloop"));
+ &jbe (&label("grandloop"));
&set_label("short");
&add ($len,16*6);
--
1.8.3.1

View File

@ -1,65 +0,0 @@
commit 919925673d6c9cfed3c1085497f5dfbbed5fc431
Author: Alex Chernyakhovsky <achernya@google.com>
Date: Thu Jun 16 12:00:22 2022 +1000
Fix AES OCB encrypt/decrypt for x86 AES-NI
aesni_ocb_encrypt and aesni_ocb_decrypt operate by having a fast-path
that performs operations on 6 16-byte blocks concurrently (the
"grandloop") and then proceeds to handle the "short" tail (which can
be anywhere from 0 to 5 blocks) that remain.
As part of initialization, the assembly initializes $len to the true
length, less 96 bytes and converts it to a pointer so that the $inp
can be compared to it. Each iteration of "grandloop" checks to see if
there's a full 96-byte chunk to process, and if so, continues. Once
this has been exhausted, it falls through to "short", which handles
the remaining zero to five blocks.
Unfortunately, the jump at the end of "grandloop" had a fencepost
error, doing a `jb` ("jump below") rather than `jbe` (jump below or
equal). This should be `jbe`, as $inp is pointing to the *end* of the
chunk currently being handled. If $inp == $len, that means that
there's a whole 96-byte chunk waiting to be handled. If $inp > $len,
then there's 5 or fewer 16-byte blocks left to be handled, and the
fall-through is intended.
The net effect of `jb` instead of `jbe` is that the last 16-byte block
of the last 96-byte chunk was completely omitted. The contents of
`out` in this position were never written to. Additionally, since
those bytes were never processed, the authentication tag generated is
also incorrect.
The same fencepost error, and identical logic, exists in both
aesni_ocb_encrypt and aesni_ocb_decrypt.
This addresses CVE-2022-2097.
Co-authored-by: Alejandro Sedeño <asedeno@google.com>
Co-authored-by: David Benjamin <davidben@google.com>
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
diff --git a/crypto/aes/asm/aesni-x86.pl b/crypto/aes/asm/aesni-x86.pl
index fe2b26542a..812758e02e 100644
--- a/crypto/aes/asm/aesni-x86.pl
+++ b/crypto/aes/asm/aesni-x86.pl
@@ -2027,7 +2027,7 @@ my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out);
&movdqu (&QWP(-16*2,$out,$inp),$inout4);
&movdqu (&QWP(-16*1,$out,$inp),$inout5);
&cmp ($inp,$len); # done yet?
- &jb (&label("grandloop"));
+ &jbe (&label("grandloop"));
&set_label("short");
&add ($len,16*6);
@@ -2453,7 +2453,7 @@ my ($l_,$block,$i1,$i3,$i5) = ($rounds_,$key_,$rounds,$len,$out);
&pxor ($rndkey1,$inout5);
&movdqu (&QWP(-16*1,$out,$inp),$inout5);
&cmp ($inp,$len); # done yet?
- &jb (&label("grandloop"));
+ &jbe (&label("grandloop"));
&set_label("short");
&add ($len,16*6);

View File

@ -1,804 +0,0 @@
From 43d8f88511991533f53680a751e9326999a6a31f Mon Sep 17 00:00:00 2001
From: Matt Caswell <matt@openssl.org>
Date: Fri, 20 Jan 2023 15:26:54 +0000
Subject: [PATCH] Fix Timing Oracle in RSA decryption
A timing based side channel exists in the OpenSSL RSA Decryption
implementation which could be sufficient to recover a plaintext across
a network in a Bleichenbacher style attack. To achieve a successful
decryption an attacker would have to be able to send a very large number
of trial messages for decryption. The vulnerability affects all RSA
padding modes: PKCS#1 v1.5, RSA-OEAP and RSASVE.
Patch written by Dmitry Belyavsky and Hubert Kario
CVE-2022-4304
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
---
crypto/bn/bn_blind.c | 14 -
crypto/bn/bn_err.c | 2 +
crypto/bn/bn_local.h | 14 +
crypto/bn/build.info | 3 +-
crypto/bn/rsa_sup_mul.c | 614 ++++++++++++++++++++++++++++++++++++++++
crypto/err/openssl.txt | 3 +-
crypto/rsa/rsa_ossl.c | 17 +-
include/crypto/bn.h | 5 +
include/openssl/bnerr.h | 1 +
9 files changed, 653 insertions(+), 20 deletions(-)
create mode 100644 crypto/bn/rsa_sup_mul.c
diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c
index 76fc7ebcff..6e9d239321 100644
--- a/crypto/bn/bn_blind.c
+++ b/crypto/bn/bn_blind.c
@@ -13,20 +13,6 @@
#define BN_BLINDING_COUNTER 32
-struct bn_blinding_st {
- BIGNUM *A;
- BIGNUM *Ai;
- BIGNUM *e;
- BIGNUM *mod; /* just a reference */
- CRYPTO_THREAD_ID tid;
- int counter;
- unsigned long flags;
- BN_MONT_CTX *m_ctx;
- int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
- const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
- CRYPTO_RWLOCK *lock;
-};
-
BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
{
BN_BLINDING *ret = NULL;
diff --git a/crypto/bn/bn_err.c b/crypto/bn/bn_err.c
index dd87c152cf..3dd8d9a568 100644
--- a/crypto/bn/bn_err.c
+++ b/crypto/bn/bn_err.c
@@ -73,6 +73,8 @@ static const ERR_STRING_DATA BN_str_functs[] = {
{ERR_PACK(ERR_LIB_BN, BN_F_BN_SET_WORDS, 0), "bn_set_words"},
{ERR_PACK(ERR_LIB_BN, BN_F_BN_STACK_PUSH, 0), "BN_STACK_push"},
{ERR_PACK(ERR_LIB_BN, BN_F_BN_USUB, 0), "BN_usub"},
+ {ERR_PACK(ERR_LIB_BN, BN_F_OSSL_BN_RSA_DO_UNBLIND, 0),
+ "ossl_bn_rsa_do_unblind"},
{0, NULL}
};
diff --git a/crypto/bn/bn_local.h b/crypto/bn/bn_local.h
index 62a969b134..4d8cb64675 100644
--- a/crypto/bn/bn_local.h
+++ b/crypto/bn/bn_local.h
@@ -283,6 +283,20 @@ struct bn_gencb_st {
} cb;
};
+struct bn_blinding_st {
+ BIGNUM *A;
+ BIGNUM *Ai;
+ BIGNUM *e;
+ BIGNUM *mod; /* just a reference */
+ CRYPTO_THREAD_ID tid;
+ int counter;
+ unsigned long flags;
+ BN_MONT_CTX *m_ctx;
+ int (*bn_mod_exp) (BIGNUM *r, const BIGNUM *a, const BIGNUM *p,
+ const BIGNUM *m, BN_CTX *ctx, BN_MONT_CTX *m_ctx);
+ CRYPTO_RWLOCK *lock;
+};
+
/*-
* BN_window_bits_for_exponent_size -- macro for sliding window mod_exp functions
*
diff --git a/crypto/bn/build.info b/crypto/bn/build.info
index b9ed5322fa..c9fe2fdada 100644
--- a/crypto/bn/build.info
+++ b/crypto/bn/build.info
@@ -5,7 +5,8 @@ SOURCE[../../libcrypto]=\
bn_kron.c bn_sqrt.c bn_gcd.c bn_prime.c bn_err.c bn_sqr.c \
{- $target{bn_asm_src} -} \
bn_recp.c bn_mont.c bn_mpi.c bn_exp2.c bn_gf2m.c bn_nist.c \
- bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c
+ bn_depr.c bn_const.c bn_x931p.c bn_intern.c bn_dh.c bn_srp.c \
+ rsa_sup_mul.c
INCLUDE[bn_exp.o]=..
diff --git a/crypto/bn/rsa_sup_mul.c b/crypto/bn/rsa_sup_mul.c
new file mode 100644
index 0000000000..acafefd5fe
--- /dev/null
+++ b/crypto/bn/rsa_sup_mul.c
@@ -0,0 +1,614 @@
+#include <openssl/e_os2.h>
+#include <stddef.h>
+#include <sys/types.h>
+#include <string.h>
+#include <openssl/bn.h>
+#include <openssl/err.h>
+#include <openssl/rsaerr.h>
+#include "internal/numbers.h"
+#include "internal/constant_time.h"
+#include "bn_local.h"
+
+# if BN_BYTES == 8
+typedef uint64_t limb_t;
+# if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ == 16
+/* nonstandard; implemented by gcc on 64-bit platforms */
+typedef __uint128_t limb2_t;
+# define HAVE_LIMB2_T
+# endif
+# define LIMB_BIT_SIZE 64
+# define LIMB_BYTE_SIZE 8
+# elif BN_BYTES == 4
+typedef uint32_t limb_t;
+typedef uint64_t limb2_t;
+# define LIMB_BIT_SIZE 32
+# define LIMB_BYTE_SIZE 4
+# define HAVE_LIMB2_T
+# else
+# error "Not supported"
+# endif
+
+/*
+ * For multiplication we're using schoolbook multiplication,
+ * so if we have two numbers, each with 6 "digits" (words)
+ * the multiplication is calculated as follows:
+ * A B C D E F
+ * x I J K L M N
+ * --------------
+ * N*F
+ * N*E
+ * N*D
+ * N*C
+ * N*B
+ * N*A
+ * M*F
+ * M*E
+ * M*D
+ * M*C
+ * M*B
+ * M*A
+ * L*F
+ * L*E
+ * L*D
+ * L*C
+ * L*B
+ * L*A
+ * K*F
+ * K*E
+ * K*D
+ * K*C
+ * K*B
+ * K*A
+ * J*F
+ * J*E
+ * J*D
+ * J*C
+ * J*B
+ * J*A
+ * I*F
+ * I*E
+ * I*D
+ * I*C
+ * I*B
+ * + I*A
+ * ==========================
+ * N*B N*D N*F
+ * + N*A N*C N*E
+ * + M*B M*D M*F
+ * + M*A M*C M*E
+ * + L*B L*D L*F
+ * + L*A L*C L*E
+ * + K*B K*D K*F
+ * + K*A K*C K*E
+ * + J*B J*D J*F
+ * + J*A J*C J*E
+ * + I*B I*D I*F
+ * + I*A I*C I*E
+ *
+ * 1+1 1+3 1+5
+ * 1+0 1+2 1+4
+ * 0+1 0+3 0+5
+ * 0+0 0+2 0+4
+ *
+ * 0 1 2 3 4 5 6
+ * which requires n^2 multiplications and 2n full length additions
+ * as we can keep every other result of limb multiplication in two separate
+ * limbs
+ */
+
+#if defined HAVE_LIMB2_T
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
+{
+ limb2_t t;
+ /*
+ * this is idiomatic code to tell compiler to use the native mul
+ * those three lines will actually compile to single instruction
+ */
+
+ t = (limb2_t)a * b;
+ *hi = t >> LIMB_BIT_SIZE;
+ *lo = (limb_t)t;
+}
+#elif (BN_BYTES == 8) && (defined _MSC_VER)
+/* https://learn.microsoft.com/en-us/cpp/intrinsics/umul128?view=msvc-170 */
+#pragma intrinsic(_umul128)
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
+{
+ *lo = _umul128(a, b, hi);
+}
+#else
+/*
+ * if the compiler doesn't have either a 128bit data type nor a "return
+ * high 64 bits of multiplication"
+ */
+static ossl_inline void _mul_limb(limb_t *hi, limb_t *lo, limb_t a, limb_t b)
+{
+ limb_t a_low = (limb_t)(uint32_t)a;
+ limb_t a_hi = a >> 32;
+ limb_t b_low = (limb_t)(uint32_t)b;
+ limb_t b_hi = b >> 32;
+
+ limb_t p0 = a_low * b_low;
+ limb_t p1 = a_low * b_hi;
+ limb_t p2 = a_hi * b_low;
+ limb_t p3 = a_hi * b_hi;
+
+ uint32_t cy = (uint32_t)(((p0 >> 32) + (uint32_t)p1 + (uint32_t)p2) >> 32);
+
+ *lo = p0 + (p1 << 32) + (p2 << 32);
+ *hi = p3 + (p1 >> 32) + (p2 >> 32) + cy;
+}
+#endif
+
+/* add two limbs with carry in, return carry out */
+static ossl_inline limb_t _add_limb(limb_t *ret, limb_t a, limb_t b, limb_t carry)
+{
+ limb_t carry1, carry2, t;
+ /*
+ * `c = a + b; if (c < a)` is idiomatic code that makes compilers
+ * use add with carry on assembly level
+ */
+
+ *ret = a + carry;
+ if (*ret < a)
+ carry1 = 1;
+ else
+ carry1 = 0;
+
+ t = *ret;
+ *ret = t + b;
+ if (*ret < t)
+ carry2 = 1;
+ else
+ carry2 = 0;
+
+ return carry1 + carry2;
+}
+
+/*
+ * add two numbers of the same size, return overflow
+ *
+ * add a to b, place result in ret; all arrays need to be n limbs long
+ * return overflow from addition (0 or 1)
+ */
+static ossl_inline limb_t add(limb_t *ret, limb_t *a, limb_t *b, size_t n)
+{
+ limb_t c = 0;
+ ossl_ssize_t i;
+
+ for(i = n - 1; i > -1; i--)
+ c = _add_limb(&ret[i], a[i], b[i], c);
+
+ return c;
+}
+
+/*
+ * return number of limbs necessary for temporary values
+ * when multiplying numbers n limbs large
+ */
+static ossl_inline size_t mul_limb_numb(size_t n)
+{
+ return 2 * n * 2;
+}
+
+/*
+ * multiply two numbers of the same size
+ *
+ * multiply a by b, place result in ret; a and b need to be n limbs long
+ * ret needs to be 2*n limbs long, tmp needs to be mul_limb_numb(n) limbs
+ * long
+ */
+static void limb_mul(limb_t *ret, limb_t *a, limb_t *b, size_t n, limb_t *tmp)
+{
+ limb_t *r_odd, *r_even;
+ size_t i, j, k;
+
+ r_odd = tmp;
+ r_even = &tmp[2 * n];
+
+ memset(ret, 0, 2 * n * sizeof(limb_t));
+
+ for (i = 0; i < n; i++) {
+ for (k = 0; k < i + n + 1; k++) {
+ r_even[k] = 0;
+ r_odd[k] = 0;
+ }
+ for (j = 0; j < n; j++) {
+ /*
+ * place results from even and odd limbs in separate arrays so that
+ * we don't have to calculate overflow every time we get individual
+ * limb multiplication result
+ */
+ if (j % 2 == 0)
+ _mul_limb(&r_even[i + j], &r_even[i + j + 1], a[i], b[j]);
+ else
+ _mul_limb(&r_odd[i + j], &r_odd[i + j + 1], a[i], b[j]);
+ }
+ /*
+ * skip the least significant limbs when adding multiples of
+ * more significant limbs (they're zero anyway)
+ */
+ add(ret, ret, r_even, n + i + 1);
+ add(ret, ret, r_odd, n + i + 1);
+ }
+}
+
+/* modifies the value in place by performing a right shift by one bit */
+static ossl_inline void rshift1(limb_t *val, size_t n)
+{
+ limb_t shift_in = 0, shift_out = 0;
+ size_t i;
+
+ for (i = 0; i < n; i++) {
+ shift_out = val[i] & 1;
+ val[i] = shift_in << (LIMB_BIT_SIZE - 1) | (val[i] >> 1);
+ shift_in = shift_out;
+ }
+}
+
+/* extend the LSB of flag to all bits of limb */
+static ossl_inline limb_t mk_mask(limb_t flag)
+{
+ flag |= flag << 1;
+ flag |= flag << 2;
+ flag |= flag << 4;
+ flag |= flag << 8;
+ flag |= flag << 16;
+#if (LIMB_BYTE_SIZE == 8)
+ flag |= flag << 32;
+#endif
+ return flag;
+}
+
+/*
+ * copy from either a or b to ret based on flag
+ * when flag == 0, then copies from b
+ * when flag == 1, then copies from a
+ */
+static ossl_inline void cselect(limb_t flag, limb_t *ret, limb_t *a, limb_t *b, size_t n)
+{
+ /*
+ * would be more efficient with non volatile mask, but then gcc
+ * generates code with jumps
+ */
+ volatile limb_t mask;
+ size_t i;
+
+ mask = mk_mask(flag);
+ for (i = 0; i < n; i++) {
+#if (LIMB_BYTE_SIZE == 8)
+ ret[i] = constant_time_select_64(mask, a[i], b[i]);
+#else
+ ret[i] = constant_time_select_32(mask, a[i], b[i]);
+#endif
+ }
+}
+
+static limb_t _sub_limb(limb_t *ret, limb_t a, limb_t b, limb_t borrow)
+{
+ limb_t borrow1, borrow2, t;
+ /*
+ * while it doesn't look constant-time, this is idiomatic code
+ * to tell compilers to use the carry bit from subtraction
+ */
+
+ *ret = a - borrow;
+ if (*ret > a)
+ borrow1 = 1;
+ else
+ borrow1 = 0;
+
+ t = *ret;
+ *ret = t - b;
+ if (*ret > t)
+ borrow2 = 1;
+ else
+ borrow2 = 0;
+
+ return borrow1 + borrow2;
+}
+
+/*
+ * place the result of a - b into ret, return the borrow bit.
+ * All arrays need to be n limbs long
+ */
+static limb_t sub(limb_t *ret, limb_t *a, limb_t *b, size_t n)
+{
+ limb_t borrow = 0;
+ ossl_ssize_t i;
+
+ for (i = n - 1; i > -1; i--)
+ borrow = _sub_limb(&ret[i], a[i], b[i], borrow);
+
+ return borrow;
+}
+
+/* return the number of limbs necessary to allocate for the mod() tmp operand */
+static ossl_inline size_t mod_limb_numb(size_t anum, size_t modnum)
+{
+ return (anum + modnum) * 3;
+}
+
+/*
+ * calculate a % mod, place the result in ret
+ * size of a is defined by anum, size of ret and mod is modnum,
+ * size of tmp is returned by mod_limb_numb()
+ */
+static void mod(limb_t *ret, limb_t *a, size_t anum, limb_t *mod,
+ size_t modnum, limb_t *tmp)
+{
+ limb_t *atmp, *modtmp, *rettmp;
+ limb_t res;
+ size_t i;
+
+ memset(tmp, 0, mod_limb_numb(anum, modnum) * LIMB_BYTE_SIZE);
+
+ atmp = tmp;
+ modtmp = &tmp[anum + modnum];
+ rettmp = &tmp[(anum + modnum) * 2];
+
+ for (i = modnum; i <modnum + anum; i++)
+ atmp[i] = a[i-modnum];
+
+ for (i = 0; i < modnum; i++)
+ modtmp[i] = mod[i];
+
+ for (i = 0; i < anum * LIMB_BIT_SIZE; i++) {
+ rshift1(modtmp, anum + modnum);
+ res = sub(rettmp, atmp, modtmp, anum+modnum);
+ cselect(res, atmp, atmp, rettmp, anum+modnum);
+ }
+
+ memcpy(ret, &atmp[anum], sizeof(limb_t) * modnum);
+}
+
+/* necessary size of tmp for a _mul_add_limb() call with provided anum */
+static ossl_inline size_t _mul_add_limb_numb(size_t anum)
+{
+ return 2 * (anum + 1);
+}
+
+/* multiply a by m, add to ret, return carry */
+static limb_t _mul_add_limb(limb_t *ret, limb_t *a, size_t anum,
+ limb_t m, limb_t *tmp)
+{
+ limb_t carry = 0;
+ limb_t *r_odd, *r_even;
+ size_t i;
+
+ memset(tmp, 0, sizeof(limb_t) * (anum + 1) * 2);
+
+ r_odd = tmp;
+ r_even = &tmp[anum + 1];
+
+ for (i = 0; i < anum; i++) {
+ /*
+ * place the results from even and odd limbs in separate arrays
+ * so that we have to worry about carry just once
+ */
+ if (i % 2 == 0)
+ _mul_limb(&r_even[i], &r_even[i + 1], a[i], m);
+ else
+ _mul_limb(&r_odd[i], &r_odd[i + 1], a[i], m);
+ }
+ /* assert: add() carry here will be equal zero */
+ add(r_even, r_even, r_odd, anum + 1);
+ /*
+ * while here it will not overflow as the max value from multiplication
+ * is -2 while max overflow from addition is 1, so the max value of
+ * carry is -1 (i.e. max int)
+ */
+ carry = add(ret, ret, &r_even[1], anum) + r_even[0];
+
+ return carry;
+}
+
+static ossl_inline size_t mod_montgomery_limb_numb(size_t modnum)
+{
+ return modnum * 2 + _mul_add_limb_numb(modnum);
+}
+
+/*
+ * calculate a % mod, place result in ret
+ * assumes that a is in Montgomery form with the R (Montgomery modulus) being
+ * smallest power of two big enough to fit mod and that's also a power
+ * of the count of number of bits in limb_t (B).
+ * For calculation, we also need n', such that mod * n' == -1 mod B.
+ * anum must be <= 2 * modnum
+ * ret needs to be modnum words long
+ * tmp needs to be mod_montgomery_limb_numb(modnum) limbs long
+ */
+static void mod_montgomery(limb_t *ret, limb_t *a, size_t anum, limb_t *mod,
+ size_t modnum, limb_t ni0, limb_t *tmp)
+{
+ limb_t carry, v;
+ limb_t *res, *rp, *tmp2;
+ ossl_ssize_t i;
+
+ res = tmp;
+ /*
+ * for intermediate result we need an integer twice as long as modulus
+ * but keep the input in the least significant limbs
+ */
+ memset(res, 0, sizeof(limb_t) * (modnum * 2));
+ memcpy(&res[modnum * 2 - anum], a, sizeof(limb_t) * anum);
+ rp = &res[modnum];
+ tmp2 = &res[modnum * 2];
+
+ carry = 0;
+
+ /* add multiples of the modulus to the value until R divides it cleanly */
+ for (i = modnum; i > 0; i--, rp--) {
+ v = _mul_add_limb(rp, mod, modnum, rp[modnum - 1] * ni0, tmp2);
+ v = v + carry + rp[-1];
+ carry |= (v != rp[-1]);
+ carry &= (v <= rp[-1]);
+ rp[-1] = v;
+ }
+
+ /* perform the final reduction by mod... */
+ carry -= sub(ret, rp, mod, modnum);
+
+ /* ...conditionally */
+ cselect(carry, ret, rp, ret, modnum);
+}
+
+/* allocated buffer should be freed afterwards */
+static void BN_to_limb(const BIGNUM *bn, limb_t *buf, size_t limbs)
+{
+ int i;
+ int real_limbs = (BN_num_bytes(bn) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
+ limb_t *ptr = buf + (limbs - real_limbs);
+
+ for (i = 0; i < real_limbs; i++)
+ ptr[i] = bn->d[real_limbs - i - 1];
+}
+
+#if LIMB_BYTE_SIZE == 8
+static ossl_inline uint64_t be64(uint64_t host)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = { 1 };
+
+ if (is_endian.little) {
+ uint64_t big = 0;
+
+ big |= (host & 0xff00000000000000) >> 56;
+ big |= (host & 0x00ff000000000000) >> 40;
+ big |= (host & 0x0000ff0000000000) >> 24;
+ big |= (host & 0x000000ff00000000) >> 8;
+ big |= (host & 0x00000000ff000000) << 8;
+ big |= (host & 0x0000000000ff0000) << 24;
+ big |= (host & 0x000000000000ff00) << 40;
+ big |= (host & 0x00000000000000ff) << 56;
+ return big;
+ } else {
+ return host;
+ }
+}
+
+#else
+/* Not all platforms have htobe32(). */
+static ossl_inline uint32_t be32(uint32_t host)
+{
+ const union {
+ long one;
+ char little;
+ } is_endian = { 1 };
+
+ if (is_endian.little) {
+ uint32_t big = 0;
+
+ big |= (host & 0xff000000) >> 24;
+ big |= (host & 0x00ff0000) >> 8;
+ big |= (host & 0x0000ff00) << 8;
+ big |= (host & 0x000000ff) << 24;
+ return big;
+ } else {
+ return host;
+ }
+}
+#endif
+
+/*
+ * We assume that intermediate, possible_arg2, blinding, and ctx are used
+ * similar to BN_BLINDING_invert_ex() arguments.
+ * to_mod is RSA modulus.
+ * buf and num is the serialization buffer and its length.
+ *
+ * Here we use classic/Montgomery multiplication and modulo. After the calculation finished
+ * we serialize the new structure instead of BIGNUMs taking endianness into account.
+ */
+int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate,
+ const BN_BLINDING *blinding,
+ const BIGNUM *possible_arg2,
+ const BIGNUM *to_mod, BN_CTX *ctx,
+ unsigned char *buf, int num)
+{
+ limb_t *l_im = NULL, *l_mul = NULL, *l_mod = NULL;
+ limb_t *l_ret = NULL, *l_tmp = NULL, l_buf;
+ size_t l_im_count = 0, l_mul_count = 0, l_size = 0, l_mod_count = 0;
+ size_t l_tmp_count = 0;
+ int ret = 0;
+ size_t i;
+ unsigned char *tmp;
+ const BIGNUM *arg1 = intermediate;
+ const BIGNUM *arg2 = (possible_arg2 == NULL) ? blinding->Ai : possible_arg2;
+
+ l_im_count = (BN_num_bytes(arg1) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
+ l_mul_count = (BN_num_bytes(arg2) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
+ l_mod_count = (BN_num_bytes(to_mod) + LIMB_BYTE_SIZE - 1) / LIMB_BYTE_SIZE;
+
+ l_size = l_im_count > l_mul_count ? l_im_count : l_mul_count;
+ l_im = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE);
+ l_mul = OPENSSL_zalloc(l_size * LIMB_BYTE_SIZE);
+ l_mod = OPENSSL_zalloc(l_mod_count * LIMB_BYTE_SIZE);
+
+ if ((l_im == NULL) || (l_mul == NULL) || (l_mod == NULL))
+ goto err;
+
+ BN_to_limb(arg1, l_im, l_size);
+ BN_to_limb(arg2, l_mul, l_size);
+ BN_to_limb(to_mod, l_mod, l_mod_count);
+
+ l_ret = OPENSSL_malloc(2 * l_size * LIMB_BYTE_SIZE);
+
+ if (blinding->m_ctx != NULL) {
+ l_tmp_count = mul_limb_numb(l_size) > mod_montgomery_limb_numb(l_mod_count) ?
+ mul_limb_numb(l_size) : mod_montgomery_limb_numb(l_mod_count);
+ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE);
+ } else {
+ l_tmp_count = mul_limb_numb(l_size) > mod_limb_numb(2 * l_size, l_mod_count) ?
+ mul_limb_numb(l_size) : mod_limb_numb(2 * l_size, l_mod_count);
+ l_tmp = OPENSSL_malloc(l_tmp_count * LIMB_BYTE_SIZE);
+ }
+
+ if ((l_ret == NULL) || (l_tmp == NULL))
+ goto err;
+
+ if (blinding->m_ctx != NULL) {
+ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp);
+ mod_montgomery(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count,
+ blinding->m_ctx->n0[0], l_tmp);
+ } else {
+ limb_mul(l_ret, l_im, l_mul, l_size, l_tmp);
+ mod(l_ret, l_ret, 2 * l_size, l_mod, l_mod_count, l_tmp);
+ }
+
+ /* modulus size in bytes can be equal to num but after limbs conversion it becomes bigger */
+ if (num < BN_num_bytes(to_mod)) {
+ BNerr(BN_F_OSSL_BN_RSA_DO_UNBLIND, ERR_R_PASSED_INVALID_ARGUMENT);
+ goto err;
+ }
+
+ memset(buf, 0, num);
+ tmp = buf + num - BN_num_bytes(to_mod);
+ for (i = 0; i < l_mod_count; i++) {
+#if LIMB_BYTE_SIZE == 8
+ l_buf = be64(l_ret[i]);
+#else
+ l_buf = be32(l_ret[i]);
+#endif
+ if (i == 0) {
+ int delta = LIMB_BYTE_SIZE - ((l_mod_count * LIMB_BYTE_SIZE) - num);
+
+ memcpy(tmp, ((char *)&l_buf) + LIMB_BYTE_SIZE - delta, delta);
+ tmp += delta;
+ } else {
+ memcpy(tmp, &l_buf, LIMB_BYTE_SIZE);
+ tmp += LIMB_BYTE_SIZE;
+ }
+ }
+ ret = num;
+
+ err:
+ OPENSSL_free(l_im);
+ OPENSSL_free(l_mul);
+ OPENSSL_free(l_mod);
+ OPENSSL_free(l_tmp);
+ OPENSSL_free(l_ret);
+
+ return ret;
+}
diff --git a/crypto/err/openssl.txt b/crypto/err/openssl.txt
index 9f91a4a811..ba3a46d5b9 100644
--- a/crypto/err/openssl.txt
+++ b/crypto/err/openssl.txt
@@ -1,4 +1,4 @@
-# Copyright 1999-2021 The OpenSSL Project Authors. All Rights Reserved.
+# Copyright 1999-2023 The OpenSSL Project Authors. All Rights Reserved.
#
# Licensed under the OpenSSL license (the "License"). You may not use
# this file except in compliance with the License. You can obtain a copy
@@ -232,6 +232,7 @@ BN_F_BN_RSHIFT:146:BN_rshift
BN_F_BN_SET_WORDS:144:bn_set_words
BN_F_BN_STACK_PUSH:148:BN_STACK_push
BN_F_BN_USUB:115:BN_usub
+BN_F_OSSL_BN_RSA_DO_UNBLIND:151:ossl_bn_rsa_do_unblind
BUF_F_BUF_MEM_GROW:100:BUF_MEM_grow
BUF_F_BUF_MEM_GROW_CLEAN:105:BUF_MEM_grow_clean
BUF_F_BUF_MEM_NEW:101:BUF_MEM_new
diff --git a/crypto/rsa/rsa_ossl.c b/crypto/rsa/rsa_ossl.c
index b52a66f6a6..6c3c0cf78d 100644
--- a/crypto/rsa/rsa_ossl.c
+++ b/crypto/rsa/rsa_ossl.c
@@ -465,11 +465,20 @@ static int rsa_ossl_private_decrypt(int flen, const unsigned char *from,
BN_free(d);
}
- if (blinding)
- if (!rsa_blinding_invert(blinding, ret, unblind, ctx))
+ if (blinding) {
+ /*
+ * ossl_bn_rsa_do_unblind() combines blinding inversion and
+ * 0-padded BN BE serialization
+ */
+ j = ossl_bn_rsa_do_unblind(ret, blinding, unblind, rsa->n, ctx,
+ buf, num);
+ if (j == 0)
goto err;
-
- j = BN_bn2binpad(ret, buf, num);
+ } else {
+ j = BN_bn2binpad(ret, buf, num);
+ if (j < 0)
+ goto err;
+ }
switch (padding) {
case RSA_PKCS1_PADDING:
diff --git a/include/crypto/bn.h b/include/crypto/bn.h
index 60afda1dad..b5f36fb25a 100644
--- a/include/crypto/bn.h
+++ b/include/crypto/bn.h
@@ -86,5 +86,10 @@ int bn_lshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
int bn_rshift_fixed_top(BIGNUM *r, const BIGNUM *a, int n);
int bn_div_fixed_top(BIGNUM *dv, BIGNUM *rem, const BIGNUM *m,
const BIGNUM *d, BN_CTX *ctx);
+int ossl_bn_rsa_do_unblind(const BIGNUM *intermediate,
+ const BN_BLINDING *blinding,
+ const BIGNUM *possible_arg2,
+ const BIGNUM *to_mod, BN_CTX *ctx,
+ unsigned char *buf, int num);
#endif
diff --git a/include/openssl/bnerr.h b/include/openssl/bnerr.h
index 9f3c7cfaab..a0752cea52 100644
--- a/include/openssl/bnerr.h
+++ b/include/openssl/bnerr.h
@@ -72,6 +72,7 @@ int ERR_load_BN_strings(void);
# define BN_F_BN_SET_WORDS 144
# define BN_F_BN_STACK_PUSH 148
# define BN_F_BN_USUB 115
+# define BN_F_OSSL_BN_RSA_DO_UNBLIND 151
/*
* BN reason codes.
--
2.34.1

View File

@ -0,0 +1,90 @@
diff -Naur a/crypto/pkcs12/p12_add.c b/crypto/pkcs12/p12_add.c
--- a/crypto/pkcs12/p12_add.c 2024-02-02 15:39:27.287368573 +0800
+++ b/crypto/pkcs12/p12_add.c 2024-02-02 15:38:30.271860109 +0800
@@ -76,6 +76,12 @@
PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
+
+ if (p7->d.data == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_P7DATA, PKCS12_R_DECODE_ERROR);
+ return NULL;
+ }
+
return ASN1_item_unpack(p7->d.data, ASN1_ITEM_rptr(PKCS12_SAFEBAGS));
}
@@ -132,6 +138,11 @@
{
if (!PKCS7_type_is_encrypted(p7))
return NULL;
+
+ if (p7->d.encrypted == NULL) {
+ return NULL;
+ }
+
return PKCS12_item_decrypt_d2i(p7->d.encrypted->enc_data->algorithm,
ASN1_ITEM_rptr(PKCS12_SAFEBAGS),
pass, passlen,
@@ -159,6 +170,11 @@
PKCS12_R_CONTENT_TYPE_NOT_DATA);
return NULL;
}
+ if (p12->authsafes->d.data == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_UNPACK_AUTHSAFES, PKCS12_R_DECODE_ERROR);
+ return NULL;
+ }
+
return ASN1_item_unpack(p12->authsafes->d.data,
ASN1_ITEM_rptr(PKCS12_AUTHSAFES));
}
diff -Naur a/crypto/pkcs12/p12_mutl.c b/crypto/pkcs12/p12_mutl.c
--- a/crypto/pkcs12/p12_mutl.c 2024-02-02 15:39:27.287368573 +0800
+++ b/crypto/pkcs12/p12_mutl.c 2024-02-02 15:38:30.271860109 +0800
@@ -93,6 +93,11 @@
return 0;
}
+ if (p12->authsafes->d.data == NULL) {
+ PKCS12err(PKCS12_F_PKCS12_GEN_MAC, PKCS12_R_DECODE_ERROR);
+ return 0;
+ }
+
salt = p12->mac->salt->data;
saltlen = p12->mac->salt->length;
if (!p12->mac->iter)
diff -Naur a/crypto/pkcs12/p12_npas.c b/crypto/pkcs12/p12_npas.c
--- a/crypto/pkcs12/p12_npas.c 2024-02-02 15:39:27.287368573 +0800
+++ b/crypto/pkcs12/p12_npas.c 2024-02-02 15:38:30.271860109 +0800
@@ -78,8 +78,9 @@
bags = PKCS12_unpack_p7data(p7);
} else if (bagnid == NID_pkcs7_encrypted) {
bags = PKCS12_unpack_p7encdata(p7, oldpass, -1);
- if (!alg_get(p7->d.encrypted->enc_data->algorithm,
- &pbe_nid, &pbe_iter, &pbe_saltlen))
+ if (p7->d.encrypted == NULL
+ || !alg_get(p7->d.encrypted->enc_data->algorithm,
+ &pbe_nid, &pbe_iter, &pbe_saltlen))
goto err;
} else {
continue;
diff -Naur a/crypto/pkcs7/pk7_mime.c b/crypto/pkcs7/pk7_mime.c
--- a/crypto/pkcs7/pk7_mime.c 2024-02-02 15:39:27.280368511 +0800
+++ b/crypto/pkcs7/pk7_mime.c 2024-02-02 15:38:30.263860038 +0800
@@ -30,10 +30,14 @@
{
STACK_OF(X509_ALGOR) *mdalgs;
int ctype_nid = OBJ_obj2nid(p7->type);
- if (ctype_nid == NID_pkcs7_signed)
+
+ if (ctype_nid == NID_pkcs7_signed) {
+ if (p7->d.sign == NULL)
+ return 0;
mdalgs = p7->d.sign->md_algs;
- else
+ } else {
mdalgs = NULL;
+ }
flags ^= SMIME_OLDMIME;

View File

@ -0,0 +1,74 @@
From fa3d5b8af929c296f4d684345dedf1e2b4b390e2 Mon Sep 17 00:00:00 2001
From: gaoyusong <gaoyusong2@huawei.com>
Date: Fri, 30 Sep 2022 12:10:15 +0800
Subject: [PATCH] PKCS7 sign and verify support SM2 algorithm
Signed-off-by: Huaxin Lu <luhuaxin1@huawei.com>
---
crypto/pkcs7/pk7_doit.c | 23 +++++++++++++++++++++--
crypto/sm2/sm2_pmeth.c | 1 +
2 files changed, 22 insertions(+), 2 deletions(-)
diff --git a/crypto/pkcs7/pk7_doit.c b/crypto/pkcs7/pk7_doit.c
index f63fbc5..916a35a 100644
--- a/crypto/pkcs7/pk7_doit.c
+++ b/crypto/pkcs7/pk7_doit.c
@@ -946,6 +946,9 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
STACK_OF(X509_ATTRIBUTE) *sk;
BIO *btmp;
EVP_PKEY *pkey;
+#ifndef OPENSSL_NO_SM2
+ EVP_PKEY_CTX *pctx = NULL;
+#endif
mdc_tmp = EVP_MD_CTX_new();
if (mdc_tmp == NULL) {
@@ -1013,7 +1016,19 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
goto err;
}
- if (!EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL))
+ pkey = X509_get0_pubkey(x509);
+ if (!pkey) {
+ ret = -1;
+ goto err;
+ }
+
+ ret =
+#ifndef OPENSSL_NO_SM2
+ EVP_PKEY_is_sm2(pkey) ?
+ EVP_DigestVerifyInit(mdc_tmp, &pctx, EVP_get_digestbynid(md_type), NULL, pkey) :
+#endif
+ EVP_VerifyInit_ex(mdc_tmp, EVP_get_digestbynid(md_type), NULL);
+ if (!ret)
goto err;
alen = ASN1_item_i2d((ASN1_VALUE *)sk, &abuf,
@@ -1036,7 +1051,11 @@ int PKCS7_signatureVerify(BIO *bio, PKCS7 *p7, PKCS7_SIGNER_INFO *si,
goto err;
}
- i = EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey);
+ i =
+#ifndef OPENSSL_NO_SM2
+ EVP_PKEY_is_sm2(pkey) ? EVP_DigestVerifyFinal(mdc_tmp, os->data, os->length) :
+#endif
+ EVP_VerifyFinal(mdc_tmp, os->data, os->length, pkey);
if (i <= 0) {
PKCS7err(PKCS7_F_PKCS7_SIGNATUREVERIFY, PKCS7_R_SIGNATURE_FAILURE);
ret = -1;
diff --git a/crypto/sm2/sm2_pmeth.c b/crypto/sm2/sm2_pmeth.c
index 1998812..53cdbe9 100644
--- a/crypto/sm2/sm2_pmeth.c
+++ b/crypto/sm2/sm2_pmeth.c
@@ -221,6 +221,7 @@ static int pkey_sm2_ctrl(EVP_PKEY_CTX *ctx, int type, int p1, void *p2)
return 1;
case EVP_PKEY_CTRL_DIGESTINIT:
+ case EVP_PKEY_CTRL_PKCS7_SIGN:
/* nothing to be inited, this is to suppress the error... */
return 1;
--
2.33.0

View File

@ -0,0 +1,621 @@
From 3f0898b2aea424f18f58a182803478f25548674e Mon Sep 17 00:00:00 2001
From: Xu Yizhou <xuyizhou1@huawei.com>
Date: Wed, 2 Nov 2022 11:13:07 +0800
Subject: [PATCH 3/3] SM4 XTS optimization for ARM by HW instruction
This patch implements the SM4 XTS optimization for ARM processor,
using SM4 HW instruction, which is an optional feature of
crypto extension for aarch64 V8.
Signed-off-by: Xu Yizhou <xuyizhou1@huawei.com>
---
crypto/evp/e_sm4.c | 28 ++
crypto/sm4/asm/sm4-armv8.pl | 498 +++++++++++++++++++++++++++++++++-
include/crypto/sm4_platform.h | 14 +
3 files changed, 537 insertions(+), 3 deletions(-)
diff --git a/crypto/evp/e_sm4.c b/crypto/evp/e_sm4.c
index eaa5ba0..da4dbd3 100644
--- a/crypto/evp/e_sm4.c
+++ b/crypto/evp/e_sm4.c
@@ -281,6 +281,34 @@ static int sm4_xts_init_key(EVP_CIPHER_CTX *ctx, const unsigned char *key,
const int bytes = EVP_CIPHER_CTX_key_length(ctx) / 2;
xctx->stream_gb = NULL;
xctx->stream = NULL;
+#ifdef HWSM4_CAPABLE
+ if (HWSM4_CAPABLE) {
+ if (enc) {
+ HWSM4_set_encrypt_key(key, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) HWSM4_encrypt;
+# ifdef HWSM4_xts_encrypt_gb
+ xctx->stream_gb = HWSM4_xts_encrypt_gb;
+# endif
+# ifdef HWSM4_xts_encrypt
+ xctx->stream = HWSM4_xts_encrypt;
+# endif
+ } else {
+ HWSM4_set_decrypt_key(key, &xctx->ks1.ks);
+ xctx->xts.block1 = (block128_f) HWSM4_decrypt;
+# ifdef HWSM4_xts_decrypt_gb
+ xctx->stream_gb = HWSM4_xts_decrypt_gb;
+# endif
+# ifdef HWSM4_xts_decrypt
+ xctx->stream = HWSM4_xts_decrypt;
+# endif
+ }
+ HWSM4_set_encrypt_key(key + bytes, &xctx->ks2.ks);
+ xctx->xts.block2 = (block128_f) HWSM4_encrypt;
+
+ xctx->xts.key1 = &xctx->ks1;
+ break;
+ } else
+#endif
#ifdef VPSM4_EX_CAPABLE
if (VPSM4_EX_CAPABLE) {
if (enc) {
diff --git a/crypto/sm4/asm/sm4-armv8.pl b/crypto/sm4/asm/sm4-armv8.pl
index dbacad2..923c1c0 100644
--- a/crypto/sm4/asm/sm4-armv8.pl
+++ b/crypto/sm4/asm/sm4-armv8.pl
@@ -11,9 +11,9 @@
# Oct 2021
#
-# $output is the last argument if it looks like a file (it has an extension)
+# $outut is the last argument if it looks like a file (it has an extension)
# $flavour is the first argument if it doesn't look like a file
-$output = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
+$outut = $#ARGV >= 0 && $ARGV[$#ARGV] =~ m|\.\w+$| ? pop : undef;
$flavour = $#ARGV >= 0 && $ARGV[0] !~ m|\.| ? shift : undef;
$0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
@@ -21,7 +21,7 @@ $0 =~ m/(.*[\/\\])[^\/\\]+$/; $dir=$1;
( $xlate="${dir}../../perlasm/arm-xlate.pl" and -f $xlate) or
die "can't locate arm-xlate.pl";
-open OUT,"| \"$^X\" $xlate $flavour \"$output\""
+open OUT,"| \"$^X\" $xlate $flavour \"$outut\""
or die "can't call $xlate: $!";
*STDOUT=*OUT;
@@ -110,6 +110,120 @@ $code.=<<___;
___
}
+sub mov_reg_to_vec() {
+ my $src0 = shift;
+ my $src1 = shift;
+ my $desv = shift;
+$code.=<<___;
+ mov $desv.d[0],$src0
+ mov $desv.d[1],$src1
+#ifdef __ARMEB__
+ rev32 $desv.16b,$desv.16b
+#endif
+___
+}
+
+sub mov_vec_to_reg() {
+ my $srcv = shift;
+ my $des0 = shift;
+ my $des1 = shift;
+$code.=<<___;
+ mov $des0,$srcv.d[0]
+ mov $des1,$srcv.d[1]
+___
+}
+
+sub compute_tweak() {
+ my $src0 = shift;
+ my $src1 = shift;
+ my $des0 = shift;
+ my $des1 = shift;
+ my $tmp0 = shift;
+ my $tmp1 = shift;
+ my $magic = shift;
+$code.=<<___;
+ extr x$tmp1,$src1,$src1,#32
+ extr $des1,$src1,$src0,#63
+ and w$tmp0,w$magic,w$tmp1,asr#31
+ eor $des0,x$tmp0,$src0,lsl#1
+___
+}
+
+sub compute_tweak_vec() {
+ my $src = shift;
+ my $des = shift;
+ my $tmp0 = shift;
+ my $tmp1 = shift;
+ my $magic = shift;
+ &rbit($tmp1,$src);
+$code.=<<___;
+ shl $des.16b, $tmp1.16b, #1
+ ext $tmp0.16b, $tmp1.16b, $tmp1.16b,#15
+ ushr $tmp0.16b, $tmp0.16b, #7
+ mul $tmp0.16b, $tmp0.16b, $magic.16b
+ eor $des.16b, $des.16b, $tmp0.16b
+___
+ &rbit($des,$des);
+}
+
+sub mov_en_to_enc(){
+ my $en = shift;
+ my $enc = shift;
+ if ($en eq "en") {
+$code.=<<___;
+ mov $enc,1
+___
+ } else {
+$code.=<<___;
+ mov $enc,0
+___
+ }
+}
+
+sub rbit() {
+ my $dst = shift;
+ my $src = shift;
+
+ if ($src and ("$src" ne "$dst")) {
+ if ($standard eq "_gb") {
+$code.=<<___;
+ rbit $dst.16b,$src.16b
+___
+ } else {
+$code.=<<___;
+ mov $dst.16b,$src.16b
+___
+ }
+ } else {
+ if ($standard eq "_gb") {
+$code.=<<___;
+ rbit $dst.16b,$src.16b
+___
+ }
+ }
+}
+
+sub rev32_armeb() {
+ my $dst = shift;
+ my $src = shift;
+
+ if ($src and ("$src" ne "$dst")) {
+$code.=<<___;
+#ifdef __ARMEB__
+ rev32 $dst.16b,$src.16b
+#else
+ mov $dst.16b,$src.16b
+#endif
+___
+ } else {
+$code.=<<___;
+#ifdef __ARMEB__
+ rev32 $dst.16b,$dst.16b
+#endif
+___
+ }
+}
+
$code=<<___;
#include "arm_arch.h"
.arch armv8-a+crypto
@@ -595,6 +709,384 @@ $code.=<<___;
.size ${prefix}_ctr32_encrypt_blocks,.-${prefix}_ctr32_encrypt_blocks
___
}}}
+
+
+{{{
+my ($inp,$out,$len,$rk1,$rk2,$ivp)=map("x$_",(0..5));
+my ($blocks)=("x2");
+my ($enc)=("x6");
+my ($remain)=("x7");
+my @twx=map("x$_",(9..24));
+my $lastBlk=("x25");
+
+my @tweak=map("v$_",(8..15));
+my @dat=map("v$_",(16..23));
+my $lastTweak=("v24");
+
+# x/w/v/q registers for compute tweak
+my ($magic)=("8");
+my ($tmp0,$tmp1)=("26","27");
+my ($qMagic,$vMagic)=("q25","v25");
+my ($vTmp0,$vTmp1)=("v26","v27");
+
+sub gen_xts_do_cipher() {
+$code.=<<___;
+.globl ${prefix}_xts_do_cipher${standard}
+.type ${prefix}_xts_do_cipher${standard},%function
+.align 5
+${prefix}_xts_do_cipher${standard}:
+ mov w$magic,0x87
+ ldr $qMagic, =0x01010101010101010101010101010187
+ // used to encrypt the XORed plaintext blocks
+ ld1 {@rks[0].4s,@rks[1].4s,@rks[2].4s,@rks[3].4s},[$rk2],#64
+ ld1 {@rks[4].4s,@rks[5].4s,@rks[6].4s,@rks[7].4s},[$rk2]
+ ld1 {@tweak[0].4s}, [$ivp]
+___
+ &rev32(@tweak[0],@tweak[0]);
+ &enc_blk(@tweak[0]);
+ &rev32(@tweak[0],@tweak[0]);
+$code.=<<___;
+ // used to encrypt the initial vector to yield the initial tweak
+ ld1 {@rks[0].4s,@rks[1].4s,@rks[2].4s,@rks[3].4s},[$rk1],#64
+ ld1 {@rks[4].4s,@rks[5].4s,@rks[6].4s,@rks[7].4s},[$rk1]
+
+ and $remain,$len,#0x0F
+ // convert length into blocks
+ lsr $blocks,$len,4
+ cmp $blocks,#1 // $len must be at least 16
+ b.lt 99f
+
+ cmp $remain,0 // if $len is a multiple of 16
+ b.eq .xts_encrypt_blocks${standard}
+ // if $len is not a multiple of 16
+ subs $blocks,$blocks,#1
+ b.eq .only_2blks_tweak${standard} // if $len is less than 32
+
+.xts_encrypt_blocks${standard}:
+___
+ &rbit(@tweak[0],@tweak[0]);
+ &rev32_armeb(@tweak[0],@tweak[0]);
+ &mov_vec_to_reg(@tweak[0],@twx[0],@twx[1]);
+ &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3],$tmp0,$tmp1,$magic);
+ &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5],$tmp0,$tmp1,$magic);
+ &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7],$tmp0,$tmp1,$magic);
+ &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9],$tmp0,$tmp1,$magic);
+ &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11],$tmp0,$tmp1,$magic);
+ &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13],$tmp0,$tmp1,$magic);
+ &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15],$tmp0,$tmp1,$magic);
+$code.=<<___;
+1:
+ cmp $blocks,#8
+___
+ &mov_reg_to_vec(@twx[0],@twx[1],@tweak[0]);
+ &compute_tweak(@twx[14],@twx[15],@twx[0],@twx[1],$tmp0,$tmp1,$magic);
+ &mov_reg_to_vec(@twx[2],@twx[3],@tweak[1]);
+ &compute_tweak(@twx[0],@twx[1],@twx[2],@twx[3],$tmp0,$tmp1,$magic);
+ &mov_reg_to_vec(@twx[4],@twx[5],@tweak[2]);
+ &compute_tweak(@twx[2],@twx[3],@twx[4],@twx[5],$tmp0,$tmp1,$magic);
+ &mov_reg_to_vec(@twx[6],@twx[7],@tweak[3]);
+ &compute_tweak(@twx[4],@twx[5],@twx[6],@twx[7],$tmp0,$tmp1,$magic);
+ &mov_reg_to_vec(@twx[8],@twx[9],@tweak[4]);
+ &compute_tweak(@twx[6],@twx[7],@twx[8],@twx[9],$tmp0,$tmp1,$magic);
+ &mov_reg_to_vec(@twx[10],@twx[11],@tweak[5]);
+ &compute_tweak(@twx[8],@twx[9],@twx[10],@twx[11],$tmp0,$tmp1,$magic);
+ &mov_reg_to_vec(@twx[12],@twx[13],@tweak[6]);
+ &compute_tweak(@twx[10],@twx[11],@twx[12],@twx[13],$tmp0,$tmp1,$magic);
+ &mov_reg_to_vec(@twx[14],@twx[15],@tweak[7]);
+ &compute_tweak(@twx[12],@twx[13],@twx[14],@twx[15],$tmp0,$tmp1,$magic);
+$code.=<<___;
+ b.lt 2f
+ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$inp],#64
+___
+ &rbit(@tweak[0],@tweak[0]);
+ &rbit(@tweak[1],@tweak[1]);
+ &rbit(@tweak[2],@tweak[2]);
+ &rbit(@tweak[3],@tweak[3]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b
+ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b
+ eor @dat[3].16b, @dat[3].16b, @tweak[3].16b
+ ld1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$inp],#64
+___
+ &rbit(@tweak[4],@tweak[4]);
+ &rbit(@tweak[5],@tweak[5]);
+ &rbit(@tweak[6],@tweak[6]);
+ &rbit(@tweak[7],@tweak[7]);
+$code.=<<___;
+ eor @dat[4].16b, @dat[4].16b, @tweak[4].16b
+ eor @dat[5].16b, @dat[5].16b, @tweak[5].16b
+ eor @dat[6].16b, @dat[6].16b, @tweak[6].16b
+ eor @dat[7].16b, @dat[7].16b, @tweak[7].16b
+___
+ &rev32(@dat[0],@dat[0]);
+ &rev32(@dat[1],@dat[1]);
+ &rev32(@dat[2],@dat[2]);
+ &rev32(@dat[3],@dat[3]);
+ &rev32(@dat[4],@dat[4]);
+ &rev32(@dat[5],@dat[5]);
+ &rev32(@dat[6],@dat[6]);
+ &rev32(@dat[7],@dat[7]);
+ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]);
+ &enc_4blks(@dat[4],@dat[5],@dat[6],@dat[7]);
+ &rev32(@dat[0],@dat[0]);
+ &rev32(@dat[1],@dat[1]);
+ &rev32(@dat[2],@dat[2]);
+ &rev32(@dat[3],@dat[3]);
+ &rev32(@dat[4],@dat[4]);
+ &rev32(@dat[5],@dat[5]);
+ &rev32(@dat[6],@dat[6]);
+ &rev32(@dat[7],@dat[7]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b
+ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b
+ eor @dat[3].16b, @dat[3].16b, @tweak[3].16b
+ eor @dat[4].16b, @dat[4].16b, @tweak[4].16b
+ eor @dat[5].16b, @dat[5].16b, @tweak[5].16b
+ eor @dat[6].16b, @dat[6].16b, @tweak[6].16b
+ eor @dat[7].16b, @dat[7].16b, @tweak[7].16b
+
+ // save the last tweak
+ mov $lastTweak.16b,@tweak[7].16b
+ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64
+ st1 {@dat[4].4s,@dat[5].4s,@dat[6].4s,@dat[7].4s},[$out],#64
+ subs $blocks,$blocks,#8
+ b.eq 100f
+ b 1b
+2:
+ // process 4 blocks
+ cmp $blocks,#4
+ b.lt 1f
+ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$inp],#64
+___
+ &rbit(@tweak[0],@tweak[0]);
+ &rbit(@tweak[1],@tweak[1]);
+ &rbit(@tweak[2],@tweak[2]);
+ &rbit(@tweak[3],@tweak[3]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b
+ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b
+ eor @dat[3].16b, @dat[3].16b, @tweak[3].16b
+___
+ &rev32(@dat[0],@dat[0]);
+ &rev32(@dat[1],@dat[1]);
+ &rev32(@dat[2],@dat[2]);
+ &rev32(@dat[3],@dat[3]);
+ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]);
+ &rev32(@dat[0],@dat[0]);
+ &rev32(@dat[1],@dat[1]);
+ &rev32(@dat[2],@dat[2]);
+ &rev32(@dat[3],@dat[3]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b
+ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b
+ eor @dat[3].16b, @dat[3].16b, @tweak[3].16b
+ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s,@dat[3].4s},[$out],#64
+ sub $blocks,$blocks,#4
+ mov @tweak[0].16b,@tweak[4].16b
+ mov @tweak[1].16b,@tweak[5].16b
+ mov @tweak[2].16b,@tweak[6].16b
+ // save the last tweak
+ mov $lastTweak.16b,@tweak[3].16b
+1:
+ // process last block
+ cmp $blocks,#1
+ b.lt 100f
+ b.gt 1f
+ ld1 {@dat[0].4s},[$inp],#16
+___
+ &rbit(@tweak[0],@tweak[0]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+___
+ &rev32(@dat[0],@dat[0]);
+ &enc_blk(@dat[0]);
+ &rev32(@dat[0],@dat[0]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ st1 {@dat[0].4s},[$out],#16
+ // save the last tweak
+ mov $lastTweak.16b,@tweak[0].16b
+ b 100f
+1: // process last 2 blocks
+ cmp $blocks,#2
+ b.gt 1f
+ ld1 {@dat[0].4s,@dat[1].4s},[$inp],#32
+___
+ &rbit(@tweak[0],@tweak[0]);
+ &rbit(@tweak[1],@tweak[1]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b
+___
+ &rev32(@dat[0],@dat[0]);
+ &rev32(@dat[1],@dat[1]);
+ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]);
+ &rev32(@dat[0],@dat[0]);
+ &rev32(@dat[1],@dat[1]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b
+ st1 {@dat[0].4s,@dat[1].4s},[$out],#32
+ // save the last tweak
+ mov $lastTweak.16b,@tweak[1].16b
+ b 100f
+1: // process last 3 blocks
+ ld1 {@dat[0].4s,@dat[1].4s,@dat[2].4s},[$inp],#48
+___
+ &rbit(@tweak[0],@tweak[0]);
+ &rbit(@tweak[1],@tweak[1]);
+ &rbit(@tweak[2],@tweak[2]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b
+ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b
+___
+ &rev32(@dat[0],@dat[0]);
+ &rev32(@dat[1],@dat[1]);
+ &rev32(@dat[2],@dat[2]);
+ &enc_4blks(@dat[0],@dat[1],@dat[2],@dat[3]);
+ &rev32(@dat[0],@dat[0]);
+ &rev32(@dat[1],@dat[1]);
+ &rev32(@dat[2],@dat[2]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[0].16b
+ eor @dat[1].16b, @dat[1].16b, @tweak[1].16b
+ eor @dat[2].16b, @dat[2].16b, @tweak[2].16b
+ st1 {@dat[0].4s,@dat[1].4s,@dat[2].4s},[$out],#48
+ // save the last tweak
+ mov $lastTweak.16b,@tweak[2].16b
+100:
+ cmp $remain,0
+ b.eq 99f
+
+// This brance calculates the last two tweaks,
+// while the encryption/decryption length is larger than 32
+.last_2blks_tweak${standard}:
+___
+ &rev32_armeb($lastTweak,$lastTweak);
+ &compute_tweak_vec($lastTweak,@tweak[1],$vTmp0,$vTmp1,$vMagic);
+ &compute_tweak_vec(@tweak[1],@tweak[2],$vTmp0,$vTmp1,$vMagic);
+$code.=<<___;
+ b .check_dec${standard}
+
+
+// This brance calculates the last two tweaks,
+// while the encryption/decryption length is less than 32, who only need two tweaks
+.only_2blks_tweak${standard}:
+ mov @tweak[1].16b,@tweak[0].16b
+___
+ &rev32_armeb(@tweak[1],@tweak[1]);
+ &compute_tweak_vec(@tweak[1],@tweak[2],$vTmp0,$vTmp1,$vMagic);
+$code.=<<___;
+ b .check_dec${standard}
+
+
+// Determine whether encryption or decryption is required.
+// The last two tweaks need to be swapped for decryption.
+.check_dec${standard}:
+ // encryption:1 decryption:0
+ cmp $enc,1
+ b.eq .prcess_last_2blks${standard}
+ mov $vTmp0.16B,@tweak[1].16b
+ mov @tweak[1].16B,@tweak[2].16b
+ mov @tweak[2].16B,$vTmp0.16b
+
+.prcess_last_2blks${standard}:
+___
+ &rev32_armeb(@tweak[1],@tweak[1]);
+ &rev32_armeb(@tweak[2],@tweak[2]);
+$code.=<<___;
+ ld1 {@dat[0].4s},[$inp],#16
+ eor @dat[0].16b, @dat[0].16b, @tweak[1].16b
+___
+ &rev32(@dat[0],@dat[0]);
+ &enc_blk(@dat[0]);
+ &rev32(@dat[0],@dat[0]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[1].16b
+ st1 {@dat[0].4s},[$out],#16
+
+ sub $lastBlk,$out,16
+ .loop${standard}:
+ subs $remain,$remain,1
+ ldrb w$tmp0,[$lastBlk,$remain]
+ ldrb w$tmp1,[$inp,$remain]
+ strb w$tmp1,[$lastBlk,$remain]
+ strb w$tmp0,[$out,$remain]
+ b.gt .loop${standard}
+ ld1 {@dat[0].4s}, [$lastBlk]
+ eor @dat[0].16b, @dat[0].16b, @tweak[2].16b
+___
+ &rev32(@dat[0],@dat[0]);
+ &enc_blk(@dat[0]);
+ &rev32(@dat[0],@dat[0]);
+$code.=<<___;
+ eor @dat[0].16b, @dat[0].16b, @tweak[2].16b
+ st1 {@dat[0].4s}, [$lastBlk]
+99:
+ ret
+.size ${prefix}_xts_do_cipher${standard},.-${prefix}_xts_do_cipher${standard}
+___
+} #end of gen_xts_do_cipher
+
+}}}
+
+{{{
+my ($enc)=("w6");
+
+sub gen_xts_cipher() {
+ my $en = shift;
+$code.=<<___;
+.globl ${prefix}_xts_${en}crypt${standard}
+.type ${prefix}_xts_${en}crypt${standard},%function
+.align 5
+${prefix}_xts_${en}crypt${standard}:
+ 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]!
+___
+ &mov_en_to_enc($en,$enc);
+$code.=<<___;
+ bl ${prefix}_xts_do_cipher${standard}
+ 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
+ ret
+.size ${prefix}_xts_${en}crypt${standard},.-${prefix}_xts_${en}crypt${standard}
+___
+
+} # end of gen_xts_cipher
+$standard="_gb";
+&gen_xts_do_cipher();
+&gen_xts_cipher("en");
+&gen_xts_cipher("de");
+$standard="";
+&gen_xts_do_cipher();
+&gen_xts_cipher("en");
+&gen_xts_cipher("de");
+}}}
########################################
{ my %opcode = (
"sm4e" => 0xcec08400,
diff --git a/include/crypto/sm4_platform.h b/include/crypto/sm4_platform.h
index 2f5a6cf..0bde96f 100644
--- a/include/crypto/sm4_platform.h
+++ b/include/crypto/sm4_platform.h
@@ -26,6 +26,10 @@
# define HWSM4_cbc_encrypt sm4_v8_cbc_encrypt
# define HWSM4_ecb_encrypt sm4_v8_ecb_encrypt
# define HWSM4_ctr32_encrypt_blocks sm4_v8_ctr32_encrypt_blocks
+# define HWSM4_xts_encrypt_gb sm4_v8_xts_encrypt_gb
+# define HWSM4_xts_decrypt_gb sm4_v8_xts_decrypt_gb
+# define HWSM4_xts_encrypt sm4_v8_xts_encrypt
+# define HWSM4_xts_decrypt sm4_v8_xts_decrypt
# endif
# endif
# endif /* OPENSSL_CPUID_OBJ */
@@ -46,6 +50,16 @@ void HWSM4_ecb_encrypt(const unsigned char *in, unsigned char *out,
void HWSM4_ctr32_encrypt_blocks(const unsigned char *in, unsigned char *out,
size_t len, const void *key,
const unsigned char ivec[16]);
+/* xts mode in GB/T 17964-2021 */
+void HWSM4_xts_encrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1,
+ const SM4_KEY *key2, const uint8_t iv[16]);
+void HWSM4_xts_decrypt_gb(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1,
+ const SM4_KEY *key2, const uint8_t iv[16]);
+/* xts mode in IEEE Std 1619-2007 */
+void HWSM4_xts_encrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1,
+ const SM4_KEY *key2, const uint8_t iv[16]);
+void HWSM4_xts_decrypt(const unsigned char *in, unsigned char *out, size_t length, const SM4_KEY *key1,
+ const SM4_KEY *key2, const uint8_t iv[16]);
# endif /* HWSM4_CAPABLE */
#ifdef VPSM4_EX_CAPABLE
--
2.36.1

Some files were not shown because too many files have changed in this diff Show More