diff options
author | Jack Lloyd <jack.lloyd@ribose.com> | 2018-01-24 11:56:02 -0500 |
---|---|---|
committer | Richard Levitte <levitte@openssl.org> | 2018-03-19 14:33:25 +0100 |
commit | 3d328a445c2ad0eff2e9e843c384711be58a7c2f (patch) | |
tree | 888d7dee8ebe744a5fd6a62a6b12c7b6b72bee83 /test | |
parent | df3a15512bd0f5ddd9f0dd74f0a058ee55b33904 (diff) |
Add SM2 signature and ECIES schemes
Reviewed-by: Rich Salz <rsalz@openssl.org>
Reviewed-by: Richard Levitte <levitte@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/4793)
Diffstat (limited to 'test')
-rw-r--r-- | test/build.info | 9 | ||||
-rw-r--r-- | test/recipes/30-test_evp_data/evppkey.txt | 14 | ||||
-rw-r--r-- | test/sm2crypttest.c | 249 | ||||
-rw-r--r-- | test/sm2sigtest.c | 238 |
4 files changed, 510 insertions, 0 deletions
diff --git a/test/build.info b/test/build.info index a4e6e78b60..45e3fddce1 100644 --- a/test/build.info +++ b/test/build.info @@ -27,6 +27,7 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN aborttest test_test \ sanitytest exdatatest bntest \ ectest ecstresstest ecdsatest gmdifftest pbelutest ideatest \ + sm2sigtest sm2crypttest \ md2test \ hmactest \ rc2test rc4test rc5test \ @@ -81,6 +82,14 @@ INCLUDE_MAIN___test_libtestutil_OLB = /INCLUDE=MAIN INCLUDE[ecdsatest]=../include DEPEND[ecdsatest]=../libcrypto libtestutil.a + SOURCE[sm2sigtest]=sm2sigtest.c + INCLUDE[sm2sigtest]=../include + DEPEND[sm2sigtest]=../libcrypto libtestutil.a + + SOURCE[sm2crypttest]=sm2crypttest.c + INCLUDE[sm2crypttest]=../include + DEPEND[sm2crypttest]=../libcrypto libtestutil.a + SOURCE[gmdifftest]=gmdifftest.c INCLUDE[gmdifftest]=../include DEPEND[gmdifftest]=../libcrypto libtestutil.a diff --git a/test/recipes/30-test_evp_data/evppkey.txt b/test/recipes/30-test_evp_data/evppkey.txt index cc08398e5b..d29fbbe730 100644 --- a/test/recipes/30-test_evp_data/evppkey.txt +++ b/test/recipes/30-test_evp_data/evppkey.txt @@ -18369,3 +18369,17 @@ SharedSecret=4E48335CB2A508C3481729F42C49CFC0A9DA673F9FA4FBD968B3C5B78DBFA869529 Derive=ffdhe8192-2 PeerKey=ffdhe8192-1-pub SharedSecret=4E48335CB2A508C3481729F42C49CFC0A9DA673F9FA4FBD968B3C5B78DBFA8695295642D1337C54229370B33068481F6A6E1B021F8B09B7C6B3E4DB581AD4C7ACF5C230A1FD4107EAE55530A8376856A65E079DE1BDA41B050E9B53A088ACADB879CCBC683A13BB925D48497BF7021FEB9DA214DD77FCBB6D0D46EC2BB9C7A9AFB93FC236E4EB61CB0F0C8E025D8CF4AF8B3B0F28B3E2CFAE6E760DC7877C71046179154FBE1A50A315C4DBA6D9E06406D389B614B1FC422C72FBB958C0A2EE21694CD32136F9CF0A1205E0D3A4B10CC9C98B3B4524A0CDC9455D3021AC44057CEF4A97E85166068769E9E644CC447095243BB90368A1CE6F0E3C69CA180F5B9D51F590A812B1375460CF10A7E718A83A2F6B00D8E28BAB45CEAB8AF0EB02988ED9221416EC061C1C4081552D3D0849D243DB473EC7B90180C3891E768DD2D7002CF505D369700CAF02A4B9DD1F2828C4ACC1F2EB47100DC2DB5620ADA971D1B0B0FAC9F9E3492B591FC85AC3DCB3826A8DA5842F4AE145FE33BFCDD0B6CD15C9836A5862EDB3D87A0CDBD724AE19A79A55D4F0BFF7870019926181933C840EACFB70FBC0EF182057DC09E06798EB4C9AAC2285F22F5D907A432C6D00CC44D07D77E77D1ACC183A174146ECFBDA26FF922CEBD2FA288EF2D23F65C0AAAD0F05DBFB6CA12446082D1F5774877483C3858442E305CF2A9637CE0EBB702DB70FF336E5B0413F3E8791960F1F0A9877C9076213D40657283D546AE52B73FF4449E60F8B6FE30D4CC0BA1ACA7A7DC155EC73C48B21477983D004261267D710D8A5E8CBD0656F1A963F248E887E8C2BF87BCAE7A0D4891BF21FCF35893584B29E18E842A23EA329ADD3D6AD994B5CBFBBFAB5A26932E8F799B2B0FA7789DE7A4A5C4B7FA81971819EA7F33B5BF6577F917BDE9C3680BCC5B15F1EAB4524A1B6DEE96B9F108A77344269A1757685D0404C832E4E0C5A29F808CFA6290316C0EBB2EF0A7431F62A5FBCDC66527AD8A04C0F10AF88C7CE1F1F22C41B71CE278BB704E88145608C28AD78402487031F6B13604CC6687161EBB78E7AF7AA0BC3CCB9AD8B00D7C01980599904B71F5DBC06A691E5638566BE36522B7FED69E24C28F8EA798BA3E9CCEB8AB8CF5651379A21A38315B05C66205616BBC6A3DD5573C9C6FBA2E3488E055E5F36857016D9300BFCE9F38D7C7CCD07FCF1EF41F8347CADCB12C400536374CF269613B05069B6D94CADA3B1F4ACBB68FA1ED175B01D840D871B3B0CDB918CDF15C79169A398C189AEA78860081DB423C89D350587E26D6D77B4C762B4F2A030345679F724CFBB08DB03E8CEB4FF0B91422BD2EB5C1C356D209049CFA2D6447F69B1E1DF0850FFBB6BB9F8D5B147765C023F76524A808456DEBF6A9134E3364DF462D4807FE6D4D036A4E59A4D56F8A30D8A27F4DFA174940B713A7E4 + +Title = SM2 tests + +PrivateKey=SM2_key1 +-----BEGIN PRIVATE KEY----- +MIGHAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBG0wawIBAQQg0JFWczAXva2An9m7 +2MaT9gIwWTFptvlKrxyO4TjMmbWhRANCAAQ5OirZ4n5DrKqrhaGdO4VZHhRAYVcX +Wt3Te/d/8Mr57Tf886i09VwDhSMmH8pmNq/mp6+ioUgqYG9cs6GLLioe +-----END PRIVATE KEY----- + +Verify = SM2_key1 +Ctrl = digest:SM3 +Input = D7AD397F6FFA5D4F7F11E7217F241607DC30618C236D2C09C1B9EA8FDADEE2E8 +Output = 3046022100AB1DB64DE7C40EDBDE6651C9B8EBDB804673DB836E5D5C7FE15DCF9ED2725037022100EBA714451FF69B0BB930B379E192E7CD5FA6E3C41C7FBD8303B799AB54A54621 diff --git a/test/sm2crypttest.c b/test/sm2crypttest.c new file mode 100644 index 0000000000..e1e00d8aa4 --- /dev/null +++ b/test/sm2crypttest.c @@ -0,0 +1,249 @@ +/* + * Copyright 2017 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 + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/rand.h> +#include "testutil.h" + +#ifndef OPENSSL_NO_SM2 + +# include <openssl/sm2.h> + +static RAND_METHOD fake_rand; +static const RAND_METHOD *saved_rand; + +static uint8_t *fake_rand_bytes = NULL; +static size_t fake_rand_bytes_offset = 0; + +static int get_faked_bytes(unsigned char *buf, int num) +{ + int i; + + if (fake_rand_bytes == NULL) + return saved_rand->bytes(buf, num); + + for (i = 0; i != num; ++i) + buf[i] = fake_rand_bytes[fake_rand_bytes_offset + i]; + fake_rand_bytes_offset += num; + return 1; +} + +static int start_fake_rand(const char *hex_bytes) +{ + /* save old rand method */ + if (!TEST_ptr(saved_rand = RAND_get_rand_method())) + return 0; + + fake_rand = *saved_rand; + /* use own random function */ + fake_rand.bytes = get_faked_bytes; + + fake_rand_bytes = OPENSSL_hexstr2buf(hex_bytes, NULL); + fake_rand_bytes_offset = 0; + + /* set new RAND_METHOD */ + if (!TEST_true(RAND_set_rand_method(&fake_rand))) + return 0; + return 1; +} + +static int restore_rand(void) +{ + OPENSSL_free(fake_rand_bytes); + fake_rand_bytes = NULL; + fake_rand_bytes_offset = 0; + if (!TEST_true(RAND_set_rand_method(saved_rand))) + return 0; + return 1; +} + +static EC_GROUP *create_EC_group(const char *p_hex, const char *a_hex, + const char *b_hex, const char *x_hex, + const char *y_hex, const char *order_hex, + const char *cof_hex) +{ + BIGNUM *p = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; + BIGNUM *g_x = NULL; + BIGNUM *g_y = NULL; + BIGNUM *order = NULL; + BIGNUM *cof = NULL; + EC_POINT *generator = NULL; + EC_GROUP *group = NULL; + + BN_hex2bn(&p, p_hex); + BN_hex2bn(&a, a_hex); + BN_hex2bn(&b, b_hex); + + group = EC_GROUP_new_curve_GFp(p, a, b, NULL); + BN_free(p); + BN_free(a); + BN_free(b); + + if (group == NULL) + return NULL; + + generator = EC_POINT_new(group); + if (generator == NULL) + return NULL; + + BN_hex2bn(&g_x, x_hex); + BN_hex2bn(&g_y, y_hex); + + if (EC_POINT_set_affine_coordinates_GFp(group, generator, g_x, g_y, NULL) == + 0) + return NULL; + + BN_free(g_x); + BN_free(g_y); + + BN_hex2bn(&order, order_hex); + BN_hex2bn(&cof, cof_hex); + + if (EC_GROUP_set_generator(group, generator, order, cof) == 0) + return NULL; + + EC_POINT_free(generator); + BN_free(order); + BN_free(cof); + + return group; +} + +static int test_sm2(const EC_GROUP *group, + const EVP_MD *digest, + const char *privkey_hex, + const char *message, + const char *k_hex, const char *ctext_hex) +{ + const size_t msg_len = strlen(message); + + BIGNUM *priv = NULL; + EC_KEY *key = NULL; + EC_POINT *pt = NULL; + unsigned char *expected = OPENSSL_hexstr2buf(ctext_hex, NULL); + + size_t ctext_len = 0; + uint8_t *ctext = NULL; + uint8_t *recovered = NULL; + size_t recovered_len = msg_len; + + int rc = 0; + + BN_hex2bn(&priv, privkey_hex); + + key = EC_KEY_new(); + EC_KEY_set_group(key, group); + EC_KEY_set_private_key(key, priv); + + pt = EC_POINT_new(group); + EC_POINT_mul(group, pt, priv, NULL, NULL, NULL); + + EC_KEY_set_public_key(key, pt); + BN_free(priv); + EC_POINT_free(pt); + + ctext_len = SM2_ciphertext_size(key, digest, msg_len); + ctext = OPENSSL_zalloc(ctext_len); + if (ctext == NULL) + goto done; + + start_fake_rand(k_hex); + rc = SM2_encrypt(key, digest, + (const uint8_t *)message, msg_len, ctext, &ctext_len); + restore_rand(); + + TEST_mem_eq(ctext, ctext_len, expected, ctext_len); + if (rc == 0) + goto done; + + recovered = OPENSSL_zalloc(msg_len); + if (recovered == NULL) + goto done; + rc = SM2_decrypt(key, digest, ctext, ctext_len, recovered, &recovered_len); + + TEST_int_eq(recovered_len, msg_len); + TEST_mem_eq(recovered, recovered_len, message, msg_len); + if (rc == 0) + return 0; + + rc = 1; + done: + + OPENSSL_free(ctext); + OPENSSL_free(recovered); + OPENSSL_free(expected); + EC_KEY_free(key); + return rc; +} + +static int sm2_crypt_test(void) +{ + int rc; + EC_GROUP *test_group = + create_EC_group + ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", + "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", + "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", + "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", + "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", + "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", + "1"); + + if (test_group == NULL) + return 0; + + rc = test_sm2(test_group, + EVP_sm3(), + "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0", + "encryption standard", + "004C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F", + "307B0220245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF1" + "7F6252E7022076CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A2" + "4B84400F01B804209C3D7360C30156FAB7C80A0276712DA9D8094A634B766D3A" + "285E07480653426D0413650053A89B41C418B0C3AAD00D886C00286467"); + + if (rc == 0) + return 0; + + /* Same test as above except using SHA-256 instead of SM3 */ + rc = test_sm2(test_group, + EVP_sha256(), + "1649AB77A00637BD5E2EFE283FBF353534AA7F7CB89463F208DDBC2920BB0DA0", + "encryption standard", + "004C62EEFD6ECFC2B95B92FD6C3D9575148AFA17425546D49018E5388D49DD7B4F", + "307B0220245C26FB68B1DDDDB12C4B6BF9F2B6D5FE60A383B0D18D1C4144ABF17F6252E7022076CB9264C2A7E88E52B19903FDC47378F605E36811F5C07423A24B84400F01B80420BE89139D07853100EFA763F60CBE30099EA3DF7F8F364F9D10A5E988E3C5AAFC0413229E6C9AEE2BB92CAD649FE2C035689785DA33"); + if (rc == 0) + return 0; + + EC_GROUP_free(test_group); + + return 1; +} + +#endif + +int setup_tests(void) +{ +#ifdef OPENSSL_NO_SM2 + TEST_note("SM2 is disabled."); +#else + ADD_TEST(sm2_crypt_test); +#endif + return 1; +} diff --git a/test/sm2sigtest.c b/test/sm2sigtest.c new file mode 100644 index 0000000000..5903b796f7 --- /dev/null +++ b/test/sm2sigtest.c @@ -0,0 +1,238 @@ +/* + * Copyright 2017 The OpenSSL Project Authors. All Rights Reserved. + * Copyright 2017 Ribose Inc. 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 + * https://www.openssl.org/source/license.html + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <openssl/bio.h> +#include <openssl/evp.h> +#include <openssl/bn.h> +#include <openssl/crypto.h> +#include <openssl/err.h> +#include <openssl/rand.h> +#include "testutil.h" + +#ifndef OPENSSL_NO_SM2 + +# include <openssl/sm2.h> + +static RAND_METHOD fake_rand; +static const RAND_METHOD *saved_rand; + +static uint8_t *fake_rand_bytes = NULL; +static size_t fake_rand_bytes_offset = 0; + +static int get_faked_bytes(unsigned char *buf, int num) +{ + int i; + + if (fake_rand_bytes == NULL) + return saved_rand->bytes(buf, num); + + for (i = 0; i != num; ++i) + buf[i] = fake_rand_bytes[fake_rand_bytes_offset + i]; + fake_rand_bytes_offset += num; + return 1; +} + +static int start_fake_rand(const char *hex_bytes) +{ + /* save old rand method */ + if (!TEST_ptr(saved_rand = RAND_get_rand_method())) + return 0; + + fake_rand = *saved_rand; + /* use own random function */ + fake_rand.bytes = get_faked_bytes; + + fake_rand_bytes = OPENSSL_hexstr2buf(hex_bytes, NULL); + fake_rand_bytes_offset = 0; + + /* set new RAND_METHOD */ + if (!TEST_true(RAND_set_rand_method(&fake_rand))) + return 0; + return 1; +} + +static int restore_rand(void) +{ + OPENSSL_free(fake_rand_bytes); + fake_rand_bytes = NULL; + fake_rand_bytes_offset = 0; + if (!TEST_true(RAND_set_rand_method(saved_rand))) + return 0; + return 1; +} + +static EC_GROUP *create_EC_group(const char *p_hex, const char *a_hex, + const char *b_hex, const char *x_hex, + const char *y_hex, const char *order_hex, + const char *cof_hex) +{ + BIGNUM *p = NULL; + BIGNUM *a = NULL; + BIGNUM *b = NULL; + BIGNUM *g_x = NULL; + BIGNUM *g_y = NULL; + BIGNUM *order = NULL; + BIGNUM *cof = NULL; + EC_POINT *generator = NULL; + EC_GROUP *group = NULL; + + BN_hex2bn(&p, p_hex); + BN_hex2bn(&a, a_hex); + BN_hex2bn(&b, b_hex); + + group = EC_GROUP_new_curve_GFp(p, a, b, NULL); + BN_free(p); + BN_free(a); + BN_free(b); + + if (group == NULL) + return NULL; + + generator = EC_POINT_new(group); + if (generator == NULL) + return NULL; + + BN_hex2bn(&g_x, x_hex); + BN_hex2bn(&g_y, y_hex); + + if (EC_POINT_set_affine_coordinates_GFp(group, generator, g_x, g_y, NULL) == + 0) + return NULL; + + BN_free(g_x); + BN_free(g_y); + + BN_hex2bn(&order, order_hex); + BN_hex2bn(&cof, cof_hex); + + if (EC_GROUP_set_generator(group, generator, order, cof) == 0) + return NULL; + + EC_POINT_free(generator); + BN_free(order); + BN_free(cof); + + return group; +} + + +static int test_sm2(const EC_GROUP *group, + const char *userid, + const char *privkey_hex, + const char *message, + const char *k_hex, const char *r_hex, const char *s_hex) +{ + const size_t msg_len = strlen(message); + int ok = -1; + BIGNUM *priv = NULL; + EC_POINT *pt = NULL; + EC_KEY *key = NULL; + ECDSA_SIG *sig = NULL; + const BIGNUM *sig_r = NULL; + const BIGNUM *sig_s = NULL; + BIGNUM *r = NULL; + BIGNUM *s = NULL; + + BN_hex2bn(&priv, privkey_hex); + + key = EC_KEY_new(); + EC_KEY_set_group(key, group); + EC_KEY_set_private_key(key, priv); + + pt = EC_POINT_new(group); + EC_POINT_mul(group, pt, priv, NULL, NULL, NULL); + EC_KEY_set_public_key(key, pt); + + start_fake_rand(k_hex); + sig = SM2_do_sign(key, EVP_sm3(), userid, (const uint8_t *)message, msg_len); + restore_rand(); + + if (sig == NULL) + return 0; + + ECDSA_SIG_get0(sig, &sig_r, &sig_s); + + BN_hex2bn(&r, r_hex); + BN_hex2bn(&s, s_hex); + + if (BN_cmp(r, sig_r) != 0) { + printf("Signature R mismatch: "); + BN_print_fp(stdout, r); + printf(" != "); + BN_print_fp(stdout, sig_r); + printf("\n"); + ok = 0; + } + if (BN_cmp(s, sig_s) != 0) { + printf("Signature S mismatch: "); + BN_print_fp(stdout, s); + printf(" != "); + BN_print_fp(stdout, sig_s); + printf("\n"); + ok = 0; + } + + ok = SM2_do_verify(key, EVP_sm3(), sig, userid, (const uint8_t *)message, msg_len); + + ECDSA_SIG_free(sig); + EC_POINT_free(pt); + EC_KEY_free(key); + BN_free(priv); + BN_free(r); + BN_free(s); + + return ok; +} + +static int sm2_sig_test(void) +{ + int rc = 0; + /* From draft-shen-sm2-ecdsa-02 */ + EC_GROUP *test_group = + create_EC_group + ("8542D69E4C044F18E8B92435BF6FF7DE457283915C45517D722EDB8B08F1DFC3", + "787968B4FA32C3FD2417842E73BBFEFF2F3C848B6831D7E0EC65228B3937E498", + "63E4C6D3B23B0C849CF84241484BFE48F61D59A5B16BA06E6E12D1DA27C5249A", + "421DEBD61B62EAB6746434EBC3CC315E32220B3BADD50BDC4C4E6C147FEDD43D", + "0680512BCBB42C07D47349D2153B70C4E5D7FDFCBFA36EA1A85841B9E46E09A2", + "8542D69E4C044F18E8B92435BF6FF7DD297720630485628D5AE74EE7C32E79B7", + "1"); + + if (test_group == NULL) + return 0; + + rc = test_sm2(test_group, + "ALICE123@YAHOO.COM", + "128B2FA8BD433C6C068C8D803DFF79792A519A55171B1B650C23661D15897263", + "message digest", + "006CB28D99385C175C94F94E934817663FC176D925DD72B727260DBAAE1FB2F96F", + "40F1EC59F793D9F49E09DCEF49130D4194F79FB1EED2CAA55BACDB49C4E755D1", + "6FC6DAC32C5D5CF10C77DFB20F7C2EB667A457872FB09EC56327A67EC7DEEBE7"); + + EC_GROUP_free(test_group); + + return rc; +} + +#endif + +int setup_tests(void) +{ +#ifdef OPENSSL_NO_SM2 + TEST_note("SM2 is disabled."); +#else + ADD_TEST(sm2_sig_test); +#endif + return 1; +} |