File 8791-add-support-for-SM4-block-cipher-algorithm.patch of Package erlang
From 0997c2ec9161015d98e6ec1740bac20666ab77e3 Mon Sep 17 00:00:00 2001
From: zeyun chen <chenzeyun.zju@gmail.com>
Date: Wed, 21 Feb 2024 16:47:43 +0800
Subject: [PATCH] add support for SM4 block cipher algorithm
---
lib/crypto/c_src/cipher.c | 21 +++++
lib/crypto/c_src/openssl_config.h | 12 +++
lib/crypto/doc/guides/algorithm_details.md | 7 ++
lib/crypto/src/crypto.erl | 19 ++++-
lib/crypto/test/crypto_SUITE.erl | 91 ++++++++++++++++++++++
5 files changed, 146 insertions(+), 4 deletions(-)
diff --git a/lib/crypto/c_src/cipher.c b/lib/crypto/c_src/cipher.c
index 034cf05049..887e2e39f4 100644
--- a/lib/crypto/c_src/cipher.c
+++ b/lib/crypto/c_src/cipher.c
@@ -72,6 +72,20 @@ static struct cipher_type_t cipher_types[] =
{{"blowfish_ecb"}, "BF-ECB", {NULL}, 0, 0, NOT_AEAD},
#endif
+#ifdef HAVE_SM4
+ {{"sm4_cbc"}, "sm4-cbc", {&EVP_sm4_cbc}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+ {{"sm4_ecb"}, "sm4-ecb", {&EVP_sm4_ecb}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+ {{"sm4_cfb"}, "sm4-cfb", {&EVP_sm4_cfb}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+ {{"sm4_ofb"}, "sm4-ofb", {&EVP_sm4_ofb}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+ {{"sm4_ctr"}, "sm4-ctr", {&EVP_sm4_ctr}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+#else
+ {{"sm4_cbc"}, "sm4-cbc", {NULL}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+ {{"sm4_ecb"}, "sm4-ecb", {NULL}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+ {{"sm4_cfb"}, "sm4-cfb", {NULL}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+ {{"sm4_ofb"}, "sm4-ofb", {NULL}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+ {{"sm4_ctr"}, "sm4-ctr", {NULL}, 16, NO_FIPS_CIPHER, NOT_AEAD},
+#endif
+
{{"aes_128_cbc"}, "aes-128-cbc", {&EVP_aes_128_cbc}, 16, 0, NOT_AEAD},
{{"aes_192_cbc"}, "aes-192-cbc", {&EVP_aes_192_cbc}, 24, 0, NOT_AEAD},
{{"aes_256_cbc"}, "aes-256-cbc", {&EVP_aes_256_cbc}, 32, 0, NOT_AEAD},
@@ -115,6 +129,13 @@ static struct cipher_type_t cipher_types[] =
{{"chacha20_poly1305"}, "chacha20-poly1305", {NULL}, 0, NO_FIPS_CIPHER | AEAD_CIPHER, {{0,0,0}}},
#endif
+#if defined(HAVE_SM4_GCM)
+ {{"sm4_gcm"}, "sm4-gcm", {NULL}, 16, NO_FIPS_CIPHER | AEAD_CIPHER | GCM_MODE, AEAD_CTRL},
+#endif
+#if defined(HAVE_SM4_CCM)
+ {{"sm4_ccm"}, "sm4-ccm", {NULL}, 16, NO_FIPS_CIPHER | AEAD_CIPHER | CCM_MODE, AEAD_CTRL},
+#endif
+
#if defined(HAVE_GCM) && defined(HAS_3_0_API)
{{"aes_128_gcm"}, "aes-128-gcm", {&EVP_aes_128_gcm}, 16, AEAD_CIPHER|GCM_MODE, AEAD_CTRL},
{{"aes_192_gcm"}, "aes-192-gcm", {&EVP_aes_192_gcm}, 24, AEAD_CIPHER|GCM_MODE, AEAD_CTRL},
diff --git a/lib/crypto/c_src/openssl_config.h b/lib/crypto/c_src/openssl_config.h
index 8a924a13f9..6320ef660a 100644
--- a/lib/crypto/c_src/openssl_config.h
+++ b/lib/crypto/c_src/openssl_config.h
@@ -181,6 +181,18 @@
# define HAVE_SHA512
#endif
+// SM4
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,1,1) \
+ && !defined(OPENSSL_NO_SM4)
+# define HAVE_SM4
+#endif
+
+#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(3,1,0) \
+ && !defined(OPENSSL_NO_SM4)
+# define HAVE_SM4_GCM
+# define HAVE_SM4_CCM
+#endif
+
// SHA3:
#if OPENSSL_VERSION_NUMBER >= PACKED_OPENSSL_VERSION_PLAIN(1,1,1)
// An error in beta releases of 1.1.1 fixed in production release
diff --git a/lib/crypto/doc/src/crypto.xml b/lib/crypto/doc/src/crypto.xml
index 6ab0d9bd19..fa7a91a21d 100644
--- a/lib/crypto/doc/src/crypto.xml
+++ b/lib/crypto/doc/src/crypto.xml
@@ -120,6 +120,11 @@
<p></p>
</item>
+ <tag>SM4</tag>
+ <item>
+ <url href="https://www.iso.org/standard/81564.html">The SM4 Block Cipher Algorithm</url>
+ </item>
+
<tag>Modes</tag>
<item>
<p></p>
diff --git a/lib/crypto/doc/src/algorithm_details.xml b/lib/crypto/doc/src/algorithm_details.xml
index 7081c25783..98c7714fa3 100644
--- a/lib/crypto/doc/src/algorithm_details.xml
+++ b/lib/crypto/doc/src/algorithm_details.xml
@@ -76,6 +76,7 @@
<row><cell><c>blowfish_ecb</c></cell> <cell>16</cell> <cell> 8</cell></row>
<row><cell><c>des_ecb</c></cell> <cell> 8</cell> <cell> 8</cell></row>
<row><cell><c>rc4</c></cell> <cell>16</cell> <cell> 1</cell></row>
+ <row><cell><c>sm4_ecb</c></cell> <cell>16</cell> <cell>16</cell></row>
<tcaption>Ciphers without IV</tcaption>
</table>
</section>
@@ -123,6 +124,10 @@
<row><cell><c>des_cfb</c></cell> <cell> 8</cell> <cell> 8</cell> <cell> 1</cell> <cell></cell></row>
<row><cell><c>des_ede3_cfb</c></cell> <cell>24</cell> <cell> 8</cell> <cell> 1</cell> <cell></cell></row>
<row><cell><c>rc2_cbc</c></cell> <cell>16</cell> <cell> 8</cell> <cell> 8</cell> <cell></cell></row>
+ <row><cell><c>sm4_cbc</c></cell> <cell>16</cell> <cell>16</cell> <cell>16</cell> <cell></cell></row>
+ <row><cell><c>sm4_cfc</c></cell> <cell>16</cell> <cell>16</cell> <cell>16</cell> <cell></cell></row>
+ <row><cell><c>sm4_ofc</c></cell> <cell>16</cell> <cell>16</cell> <cell>16</cell> <cell></cell></row>
+ <row><cell><c>sm4_ctr</c></cell> <cell>16</cell> <cell>16</cell> <cell>16</cell> <cell></cell></row>
<tcaption>Ciphers with IV</tcaption>
</table>
</section>
@@ -156,6 +161,9 @@
<row><cell><c>aes_256_gcm</c></cell> <cell>32</cell> <cell>≥1</cell> <cell>any</cell> <cell>1-16<br/>default: 16</cell> <cell>any</cell><cell>≥1.0.1</cell></row>
<row><cell><c>chacha20_poly1305</c></cell><cell>32</cell> <cell>1-16</cell> <cell>any</cell> <cell>16</cell> <cell>any</cell><cell>≥1.1.0</cell></row>
+
+ <row><cell><c>sm4_gcm</c></cell><cell>16</cell> <cell>12</cell> <cell>any</cell> <cell>16</cell> <cell>any</cell><cell>≥3.1.0</cell></row>
+ <row><cell><c>sm4_ccm</c></cell><cell>16</cell> <cell>12</cell> <cell>any</cell> <cell>16</cell> <cell>any</cell><cell>≥3.1.0</cell></row>
<tcaption>AEAD ciphers</tcaption>
</table>
</section>
diff --git a/lib/crypto/src/crypto.erl b/lib/crypto/src/crypto.erl
index 6ab0d9bd19..fa7a91a21d 100644
--- a/lib/crypto/src/crypto.erl
+++ b/lib/crypto/src/crypto.erl
@@ -606,6 +606,7 @@ dh_params() = [P, G] | [P, G, PrivateKeyBitLength]
| blowfish_ecb
| des_ecb
+ | sm4_ecb
| rc4 .
-type cipher_iv() :: aes_128_cbc
@@ -633,6 +634,11 @@ dh_params() = [P, G] | [P, G, PrivateKeyBitLength]
| aes_256_ctr
| aes_ctr
+ | sm4_cbc
+ | sm4_ofb
+ | sm4_cfb
+ | sm4_ctr
+
| blowfish_cbc
| blowfish_cfb64
| blowfish_ofb64
@@ -662,6 +668,9 @@ support all of them.
| aes_256_gcm
| aes_gcm
+ | sm4_gcm
+ | sm4_ccm
+
| chacha20_poly1305 .
@@ -1705,6 +1714,8 @@ aead_tag_len(aes_128_gcm) -> 16;
aead_tag_len(aes_192_gcm) -> 16;
aead_tag_len(aes_256_gcm) -> 16;
aead_tag_len(chacha20_poly1305) -> 16;
+aead_tag_len(sm4_gcm) -> 16;
+aead_tag_len(sm4_ccm) -> 16;
aead_tag_len(_) ->
error({badarg, "Not an AEAD cipher"}).
diff --git a/lib/crypto/test/crypto_SUITE.erl b/lib/crypto/test/crypto_SUITE.erl
index d9b3357999..f851970877 100644
--- a/lib/crypto/test/crypto_SUITE.erl
+++ b/lib/crypto/test/crypto_SUITE.erl
@@ -181,6 +181,13 @@
mac_check/1,
rc2_cbc/1,
rc4/1,
+ sm4_ecb/1,
+ sm4_cbc/1,
+ sm4_ofb/1,
+ sm4_cfb/1,
+ sm4_ctr/1,
+ sm4_gcm/1,
+ sm4_ccm/1,
ripemd160_incr_digest/0,
ripemd160_incr_msgs/0,
rsa_oaep/0,
@@ -266,6 +273,14 @@ groups() ->
{group, rc2_cbc},
{group, rc4},
+ {group, sm4_ecb},
+ {group, sm4_cbc},
+ {group, sm4_ofb},
+ {group, sm4_cfb},
+ {group, sm4_ctr},
+ {group, sm4_gcm},
+ {group, sm4_ccm},
+
{group, des_ede3_cbc},
{group, des_ede3_cfb},
{group, aes_128_cbc},
@@ -424,6 +439,13 @@ groups() ->
{blowfish_cfb64, [], [api_ng, api_ng_one_shot, api_ng_tls]},
{blowfish_ofb64, [], [api_ng, api_ng_one_shot, api_ng_tls]},
{rc4, [], [api_ng, api_ng_one_shot, api_ng_tls]},
+ {sm4_ecb, [], [api_ng, api_ng_one_shot, api_ng_tls]},
+ {sm4_cbc, [], [api_ng, api_ng_one_shot, api_ng_tls]},
+ {sm4_ofb, [], [api_ng, api_ng_one_shot, api_ng_tls]},
+ {sm4_cfb, [], [api_ng, api_ng_one_shot, api_ng_tls]},
+ {sm4_ctr, [], [api_ng, api_ng_one_shot, api_ng_tls]},
+ {sm4_gcm, [], [aead_ng, aead_bad_tag, api_ng_tls]},
+ {sm4_ccm, [], [aead_ng, aead_bad_tag, api_ng_tls]},
{chacha20_poly1305, [], [aead_ng, aead_bad_tag]},
{chacha20, [], [api_ng, api_ng_one_shot, api_ng_tls]},
{no_aes_cfb128, [], [no_support]},
@@ -3404,6 +3426,75 @@ rc4(_) ->
{rc4, <<"apaapa">>, long_msg()}
].
+%% Test Data from https://github.com/openssl/openssl/pull/9935
+sm4_ecb(_) ->
+ [{sm4_ecb, hexstr2bin("0123456789ABCDEFFEDCBA9876543210"), <<>>,
+ hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("681EDF34D206965E86B3E94F536E4246")}].
+sm4_cbc(_) ->
+ [{sm4_cbc, hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("2677F46B09C122CC975533105BD4A22AF6125F7275CE552C3A2BBCF533DE8A3B")}].
+sm4_ofb(_) ->
+ [{sm4_ofb, hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("693D9A535BAD5BB1786F53D7253A7056F2075D28B5235F58D50027E4177D2BCE")}].
+sm4_cfb(_) ->
+ [{sm4_cfb, hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("0123456789ABCDEFFEDCBA98765432100123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("693D9A535BAD5BB1786F53D7253A70569ED258A85A0467CC92AAB393DD978995")}].
+sm4_ctr(_) ->
+ [{sm4_ctr, hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD"
+ "EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFFEEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA"),
+ hexstr2bin("C2B4759E78AC3CF43D0852F4E8D5F9FD7256E8A5FCB65A350EE00630912E4449"
+ "2A0B17E1B85B060D0FBA612D8A95831638B361FD5FFACD942F081485A83CA35D")}
+ ].
+
+%% https://datatracker.ietf.org/doc/rfc8998 appendix A.1
+sm4_gcm(_) ->
+ [
+ {sm4_gcm,
+ hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB" %% PlainText
+ "CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD"
+ "EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF"
+ "EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA"),
+ hexstr2bin("00001234567800000000ABCD"), %% Nonce
+ hexstr2bin("FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2"), %% AAD
+ hexstr2bin("17F399F08C67D5EE19D0DC9969C4BB7D" %% CipherText
+ "5FD46FD3756489069157B282BB200735"
+ "D82710CA5C22F0CCFA7CBF93D496AC15"
+ "A56834CBCF98C397B4024A2691233B8D"),
+ hexstr2bin("83DE3541E4C2B58177E065A9BF7B62EC"), %% CipherTag
+ no_info
+ }
+ ].
+
+%% https://datatracker.ietf.org/doc/rfc8998 appendix A.2
+sm4_ccm(_) ->
+ [
+ {sm4_ccm,
+ hexstr2bin("0123456789ABCDEFFEDCBA9876543210"),
+ hexstr2bin("AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB" %% PlainText
+ "CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD"
+ "EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF"
+ "EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA"),
+ hexstr2bin("00001234567800000000ABCD"), %% Nonce
+ hexstr2bin("FEEDFACEDEADBEEFFEEDFACEDEADBEEFABADDAD2"), %% AAD
+ hexstr2bin("48AF93501FA62ADBCD414CCE6034D895" %% CipherText
+ "DDA1BF8F132F042098661572E7483094"
+ "FD12E518CE062C98ACEE28D95DF4416B"
+ "ED31A2F04476C18BB40C84A74B97DC5B"),
+ hexstr2bin("16842D4FA186F56AB33256971FA110F4"), %% CipherTag
+ no_info
+ }
+ ].
+
aes_128_ctr(_) ->
[ %% F.5.3 CTR-AES192.Encrypt
{aes_128_ctr, hexstr2bin("2b7e151628aed2a6abf7158809cf4f3c"),
--
2.35.3