- Sponsor
-
Notifications
You must be signed in to change notification settings - Fork 10.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
An implementation of the Chinese SM4 block cipher #4552
Conversation
The CLA bot is complaining because the commit author in two of the commits is given as "Jack Lloyd" with an email address that is not in our CLA database. |
Thank you @mattcaswell for letting us know, we'll fix that. |
Some more things to fix:
|
One more:
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code looks very neat. I just have a few (mostly style) comments. I've not verified the implementation against the spec (where is the spec?).
crypto/evp/e_sm4.c
Outdated
const SM4_KEY * key, const int enc) | ||
{ | ||
if (enc) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Remove this stray blank line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
crypto/include/internal/sm4.h
Outdated
|
||
void SM4_encrypt(const uint8_t *in, uint8_t *out, const SM4_KEY * ks); | ||
|
||
void SM4_decrypt(const uint8_t *in, uint8_t *out, const SM4_KEY * ks); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No space between '*' and ks
, i.e. it should be const SM4_KEY *ks
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
crypto/sm4/sm4.c
Outdated
|
||
static inline uint32_t SM4_T_slow(uint32_t X) | ||
{ | ||
uint32_t t = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Blank line after declaration
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
crypto/sm4/sm4.c
Outdated
for (i = 0; i != 32; ++i) { | ||
uint32_t X = K[(i + 1) % 4] ^ K[(i + 2) % 4] ^ K[(i + 3) % 4] ^ CK[i]; | ||
|
||
uint32_t t = 0; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No blank line above here - should be one below it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
crypto/sm4/sm4.c
Outdated
K[2] = load_u32_be(key, 2) ^ FK[2]; | ||
K[3] = load_u32_be(key, 3) ^ FK[3]; | ||
|
||
for (i = 0; i != 32; ++i) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably should be SM4_KEY_SCHEDULE
instead of 32?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
crypto/sm4/sm4.c
Outdated
return 1; | ||
} | ||
|
||
#define SM4_RNDS(k0,k1,k2,k3,F) do { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Leave a space after each ,
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
@@ -2078,6 +2078,36 @@ Operation = ENCRYPT | |||
Plaintext = 000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F20212223 | |||
Ciphertext = A4DA23FCE6A5FFAA6D64AE9A0652A42CD161A34B65F9679F75C01F101F71276F15EF0D8D | |||
|
|||
Title = SM4 test vectors |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What is the origin of these test vectors? Can we include a reference?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Included a reference to IETF draft-ribose-cfrg-sm4
.
test/sm4test.c
Outdated
SM4_KEY key; | ||
SM4_set_key(k, &key); | ||
|
||
uint8_t block[16]; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't use SM4_BLOCK_SIZE here - but perhaps a define instead of a magic number here (and other instances below) would be better?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually, since internal/sm4.h
is included, it's perfectly possible to use SM4_BLOCK_SIZE
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using SM4_BLOCK_SIZE
now, moved to test/sm4_internal_test.c
.
util/libcrypto.num
Outdated
EVP_sm4_cbc 4369 1_1_1 EXIST::FUNCTION:SM4 | ||
EVP_sm4_ofb 4370 1_1_1 EXIST::FUNCTION:SM4 | ||
EVP_sm4_cfb128 4371 1_1_1 EXIST::FUNCTION:SM4 | ||
EVP_sm4_ctr 4372 1_1_1 EXIST::FUNCTION:SM4 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suggest you remove these changes and do a make update
again. You'll find that the SM4_*
symbols will not appear... (that's the update of 3 symbols that's mentioned in Travis, make update
wants to change their state to NOEXIST
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@levitte I've done this. Somehow make update
on my machine adds a last line of license ... EXIST::FUNCTION
to the end, which I've removed manually... Let me know if this behavior is correct.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no idea why it adds a license
line... It shouldn't, and it doesn't for me...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @levitte for the confirmation 👍
When I looked at these a while back, the best English reference I could locate for SM4 / SMS4 is: SMS4 Encryption Algorithm for Wireless Networks. There is a much better IETF draft now. There is of course a Chinese specification but I'm unable to read it. The question in my mind is should the Chinese cryptographic primitives be wrapped in an engine like GOST is? SM4 is but one of several defined algorithms, SM2 and SM3 are also IETF drafts, albeit expired ones. I also found a reference describing SM9. I've not looked for a ZUC definition. There are more algorithms than this. |
@paulidale the Internet-Draft for SM4 is intended to fully cover the official standard GB/T 32907-2016 (in Sections 1 to 7), as well as modes of operation and some considerations that were not covered by the standard. SMS4 Encryption Algorithm for Wireless Networks is a translation based on an older standard published by OSCCA called GM/T 0002-2012, which is not currently available on the Internet. |
test/sm4_internal_test.c
Outdated
0x86, 0xb3, 0xe9, 0x4f, 0x53, 0x6e, 0x42, 0x46 | ||
}; | ||
|
||
// after 1,000,000 iterations |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Change that to a classic C comment, please
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
test/recipes/05-test_sm4.t
Outdated
|
||
use OpenSSL::Test::Simple; | ||
|
||
simple_test("test_internal_sm4", "sm4_internal_test", "sm4"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please rename this file to go along with the other internal tests. 03-test_internal_sm4.t
would be a good one.
Also, since this is only built under certain condicions, you need to add the following as well, before the simple_test
line:
plan skip_all => "This test is unsupported in a shared library build on Windows"
if $^O eq 'MSWin32' && !disabled("shared");
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done, thanks @levitte !
crypto/evp/e_sm4.c
Outdated
@@ -0,0 +1,103 @@ | |||
/* | |||
* Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. | |||
* Copyright 2017 [Ribose Inc.](https://www.ribose.com). All Rights Reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I saw in other files, seems the copyright line should contain company name without the URL (correct me if I am wrong), the []()
likes a markdown syntax...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems odd to me too. Better would be:
Copyright 2017 Ribose Inc. All Rights Reserved.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
sm4_cfb128 1137 | ||
sm4_cfb8 1138 | ||
sm4_ctr 1139 | ||
ISO_CN 1140 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should the number be aligned to others? Or the 2-tabs is fixed there?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This file is generated, so...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will feel challenged to make the generation script properly align 😉
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Haha
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ahh...
crypto/sm4/sm4.c
Outdated
}; | ||
|
||
/* | ||
* SM4_SBOX_T[j] == L(SM4_SBOX[j]). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation. And I think this could be placed in one line as /* */
...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indentation addressed.
crypto/sm4/sm4.c
Outdated
* SM4_SBOX_T[j] == L(SM4_SBOX[j]). | ||
*/ | ||
static const uint32_t SM4_SBOX_T[256] = { | ||
0x8ED55B5B, 0xD0924242, 0x4DEAA7A7, 0x06FDFBFB, 0xFCCF3333, 0x65E28787, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
4 spaces indent...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
test/recipes/03-test_internal_sm4.t
Outdated
@@ -0,0 +1,19 @@ | |||
#! /usr/bin/env perl | |||
# Copyright 2015-2016 The OpenSSL Project Authors. All Rights Reserved. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copyright 2017 The OpenSSL...?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
test/sm4_internal_test.c
Outdated
static int test_sm4_ecb(void) | ||
{ | ||
static const uint8_t k[SM4_BLOCK_SIZE] = { | ||
0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indent should be 4-spaces, so do the followings...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
crypto/sm4/sm4.c
Outdated
return 1; | ||
} | ||
|
||
#define SM4_RNDS(k0, k1, k2, k3, F) do { \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess it's preferred if the do
statement is placed in next line as:
#define macrofun(a, b, c) \
do { \
if (a == 5) \
do_this(b, c); \
} while (0)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Addressed.
And documentation is missing... |
@InfoHunter is right. There should be a new entry in the |
@ronaldtse thanks for the better links. |
@InfoHunter @levitte added new section in
Should these be added? |
They should probably all get added, but I suggest you do that in a different pull request so that we can merge that to other branches. |
crypto/sm4/sm4.c
Outdated
0x794C3535, 0xA0208080, 0x9D78E5E5, 0x56EDBBBB, 0x235E7D7D, 0xC63EF8F8, | ||
0x8BD45F5F, 0xE7C82F2F, 0xDD39E4E4, 0x68492121 }; | ||
|
||
static inline uint32_t rotl(uint32_t a, uint8_t n) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inline is not portable, use ossl_inline.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @dot-asm ! Addressed.
One last rebase. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup
It's obvious that there probably can't be a solid common criteria for deciding either way. Especially since there are contradicting cases when things look the way they do rather for backward compatibility sake than anything else. But it doesn't mean that one shouldn't attempt to formulate multiple criteria and consider combination. One of such criteria can [or should?] be public record of independent cryptanalysis... Another is ability to withstand side channel attacks... Recognized [non-proprietary] application... |
Yes, @dot-asm, you're right. And also the ability of the project to maintain these things in the face of attacks. It's an interesting question. |
BTW, siphash was previously mentioned. Note that it's not released, so one can still change that... |
A rebase is required before merge :( |
Another consideration is that enabling an algorithm wouldn't be considered API changing whereas disabling one would be. I.e. disabled by default is changeable in a minor release. |
* remove for-loop initial declarations that are only allowed in C99 * update SM4 numbers in libcrypto.num via `make update` * fix C90 issues * style fixes as commented by mattcaswell * remaining style fixes * cleanup test vectors and add reference * use SM4_KEY_SCHEDULE instead of 32 * cleanup comments * include internal test, and use SM4_BLOCK_SIZE
* add documentation * use ossl_inline for portability * remove unnecessary includes * no spaces after cast * use (uint8_t) cast instead of `& 0xFF` * use int in for loop * use `or` in load_u32_be instead of `xor`
@paulidale rebased again! |
Thanks, waiting for the Travis build to finish before merging. |
Reviewed-by: Richard Levitte <levitte@openssl.org> Reviewed-by: Paul Dale <paul.dale@oracle.com> (Merged from #4552)
Merged, thanks. |
Thank you @paulidale and everyone here ! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Some trailing white spaces in crypto/objects/objects.txt were removed during this PR. Many text editors have such feature to remove all trailing white spaces, some of these white space changes are unrelated to the current PR.
Hope we can use some .c
and .txt
formatter to remove such unnecessary trailing white spaces before more new pull requests arrives.
util/openssl-format-source -v -c
ignores crypto/objects/objects.txt, I guess.
See: https://github.com/openssl/openssl/blob/master/util/openssl-format-source
@@ -1368,7 +1368,7 @@ member-body 643 100 112 : issuerSignTool : Signing Tool of Issuer | |||
# Definitions for Camellia cipher - ECB, CFB, OFB MODE | |||
|
|||
!Alias ntt-ds 0 3 4401 5 | |||
!Alias camellia ntt-ds 3 1 9 | |||
!Alias camellia ntt-ds 3 1 9 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
An unrelated white space change here.
@@ -1498,7 +1515,7 @@ ISO-US 10046 2 1 : dhpublicnumber : X9.42 DH | |||
1 3 36 3 3 2 8 1 1 11 : brainpoolP384r1 | |||
1 3 36 3 3 2 8 1 1 12 : brainpoolP384t1 | |||
1 3 36 3 3 2 8 1 1 13 : brainpoolP512r1 | |||
1 3 36 3 3 2 8 1 1 14 : brainpoolP512t1 | |||
1 3 36 3 3 2 8 1 1 14 : brainpoolP512t1 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another unrelated white space change.
I don't think it was improper to remove these spaces here. Long ago I learned the 'style' of this project which was: "if your changes are next to a nit, then you fix the nit incidentally' ;-) |
Why these comments on a PR that was approved and merged a long time ago? |
@levitte seems that it was due to increased interest given news of OpenSSL 1.1.1 now supports these algorithms 😉👏 |
This PR introduces the Chinese SM4 algorithm which is a 128-bit block cipher.
It was originally ported from Ribose's contribution to Botan, but has received further updates to make its performance on par with the SM4 implementation there.
Currently
openssl speed -evp sm4-ecb
reports:This is a contribution by Ribose Inc. and was done with knowledge of @richsalz, @levitte, @InfoHunter.
There might be some stuff missing but please do bring on the review process 😉 .
cc: @randombit @dewyatt @erikbor
This is a contribution from Ribose Inc..
Checklist