From 252c9e17650233e873de47ee5fd18adb2c501158 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Sun, 21 Apr 2024 10:10:46 +0800 Subject: [PATCH] Add more SM4 test vectors SM4 pass openssl and other known test vectors. SM4-GCM and SM4-XTS only support the GB/T GF(2^128) encoding standard. --- CMakeLists.txt | 2 + include/gmssl/ec.h | 3 +- include/gmssl/sm4.h | 9 +- include/gmssl/sm9.h | 88 +++--- src/sm2_key.c | 5 - src/sm4_xts.c | 8 +- tests/rdrandtest.c | 63 +++++ tests/sm4_cbctest.c | 331 +++++++++++++++++++++++ tests/sm4_ccmtest.c | 112 ++++++++ tests/sm4_cfbtest.c | 108 ++++++++ tests/sm4_ctrtest.c | 373 ++++++++++++++++++++++++++ tests/sm4_ecbtest.c | 5 +- tests/sm4_gcmtest.c | 4 +- tests/sm4_ofbtest.c | 102 +++++++ tests/sm4_xtstest.c | 109 ++++++++ tests/sm4test.c | 636 +------------------------------------------- 16 files changed, 1267 insertions(+), 691 deletions(-) create mode 100644 tests/rdrandtest.c create mode 100644 tests/sm4_cbctest.c create mode 100644 tests/sm4_ctrtest.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 077439591..35d576d51 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -131,6 +131,8 @@ set(tools set(tests sm4 + sm4_cbc + sm4_ctr sm3 sm4_sm3_hmac sm2_z256 diff --git a/include/gmssl/ec.h b/include/gmssl/ec.h index 2dc1c00bb..000487929 100644 --- a/include/gmssl/ec.h +++ b/include/gmssl/ec.h @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,7 @@ enum { EC_private_key_version = 1, }; -int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); +_gmssl_export int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen); #ifdef __cplusplus } diff --git a/include/gmssl/sm4.h b/include/gmssl/sm4.h index 5b38f1441..08224bec3 100644 --- a/include/gmssl/sm4.h +++ b/include/gmssl/sm4.h @@ -175,8 +175,13 @@ _gmssl_export int sm4_ofb_encrypt_finish(SM4_OFB_CTX *ctx, uint8_t *out, size_t #ifdef ENABLE_SM4_CFB -#define SM4_CFB_MIN_SBYTES 1 -#define SM4_CFB_MAX_SBYTES 16 +#define SM4_CFB_MIN_SBYTES 1 +#define SM4_CFB_MAX_SBYTES 16 + +// pre-defined values for `sbytes` +#define SM4_CFB_8 1 +#define SM4_CFB_64 8 +#define SM4_CFB_128 16 // always call `sm4_set_encrypt_key` before encrypt/decrypt // `sm4_cfb_encrypt/decrypt` will change the param `iv` diff --git a/include/gmssl/sm9.h b/include/gmssl/sm9.h index 4908e376b..26eca7404 100644 --- a/include/gmssl/sm9.h +++ b/include/gmssl/sm9.h @@ -75,35 +75,35 @@ typedef struct { SM9_Z256_POINT ds; } SM9_SIGN_KEY; -int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master); -int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key); +_gmssl_export int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master); +_gmssl_export int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key); // algorthm,parameters = sm9,sm9sign #define SM9_SIGN_MASTER_KEY_MAX_SIZE 171 int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen); int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen); -int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen); -int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen); -int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp); -int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp); -int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk); +_gmssl_export int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen); +_gmssl_export int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen); +_gmssl_export int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp); +_gmssl_export int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp); +_gmssl_export int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk); #define SM9_SIGN_MASTER_PUBLIC_KEY_SIZE 136 -int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen); -int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen); -int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp); -int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp); -int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk); +_gmssl_export int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen); +_gmssl_export int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen); +_gmssl_export int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp); +_gmssl_export int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp); +_gmssl_export int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk); // algorithm,parameters = sm9sign, #define SM9_SIGN_KEY_SIZE 204 int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen); int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen); -int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen); -int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen); -int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp); -int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp); -int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key); +_gmssl_export int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen); +_gmssl_export int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen); +_gmssl_export int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp); +_gmssl_export int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp); +_gmssl_export int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key); /* from GM/T 0080-2020 SM9 Cryptographic Alagorithm Application Specification @@ -122,18 +122,18 @@ int sm9_do_verify(const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen, #define SM9_SIGNATURE_SIZE 104 int sm9_signature_to_der(const SM9_SIGNATURE *sig, uint8_t **out, size_t *outlen); int sm9_signature_from_der(SM9_SIGNATURE *sig, const uint8_t **in, size_t *inlen); -int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); +_gmssl_export int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen); typedef struct { SM3_CTX sm3_ctx; } SM9_SIGN_CTX; -int sm9_sign_init(SM9_SIGN_CTX *ctx); -int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); -int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen); -int sm9_verify_init(SM9_SIGN_CTX *ctx); -int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); -int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen, +_gmssl_export int sm9_sign_init(SM9_SIGN_CTX *ctx); +_gmssl_export int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); +_gmssl_export int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen); +_gmssl_export int sm9_verify_init(SM9_SIGN_CTX *ctx); +_gmssl_export int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen); +_gmssl_export int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen, const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen); @@ -161,35 +161,35 @@ typedef struct { SM9_Z256_TWIST_POINT de; } SM9_ENC_KEY; -int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master); -int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key); +_gmssl_export int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master); +_gmssl_export int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key); // algorithm,parameters = sm9,sm9encrypt #define SM9_ENC_MASTER_KEY_MAX_SIZE 105 int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen); int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen); -int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen); -int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen); -int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp); -int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp); -int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk); +_gmssl_export int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen); +_gmssl_export int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen); +_gmssl_export int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp); +_gmssl_export int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp); +_gmssl_export int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk); #define SM9_ENC_MASTER_PUBLIC_KEY_SIZE 70 -int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen); -int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen); -int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp); -int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp); -int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk); +_gmssl_export int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen); +_gmssl_export int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen); +_gmssl_export int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp); +_gmssl_export int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp); +_gmssl_export int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk); // algorithm,parameters = sm9encrypt, #define SM9_ENC_KEY_SIZE 204 int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen); int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen); -int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen); -int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen); -int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp); -int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp); -int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key); +_gmssl_export int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen); +_gmssl_export int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen); +_gmssl_export int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp); +_gmssl_export int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp); +_gmssl_export int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key); #define SM9_MAX_PRIVATE_KEY_SIZE (SM9_SIGN_KEY_SIZE) // MAX(SIGN_MASTER_KEY, SIGN_KEY, ENC_MASTER_KEY, ENC_KEY) #define SM9_MAX_PRIVATE_KEY_INFO_SIZE 512 @@ -217,10 +217,10 @@ int sm9_ciphertext_to_der(const SM9_Z256_POINT *C1, const uint8_t *c2, size_t c2 const uint8_t c3[SM3_HMAC_SIZE], uint8_t **out, size_t *outlen); int sm9_ciphertext_from_der(SM9_Z256_POINT *C1, const uint8_t **c2, size_t *c2len, const uint8_t **c3, const uint8_t **in, size_t *inlen); -int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); -int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, +_gmssl_export int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen); +_gmssl_export int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); -int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, +_gmssl_export int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen); diff --git a/src/sm2_key.c b/src/sm2_key.c index 730d0e9be..3fd93ab12 100644 --- a/src/sm2_key.c +++ b/src/sm2_key.c @@ -356,7 +356,6 @@ int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, co return -1; } -#ifdef ENABLE_SM2_PRIVATE_KEY_EXPORT int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp) { int ret = -1; @@ -405,7 +404,6 @@ int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, FILE *fp) } return 1; } -#endif int sm2_public_key_info_to_der(const SM2_KEY *pub_key, uint8_t **out, size_t *outlen) { @@ -440,8 +438,6 @@ int sm2_public_key_info_from_der(SM2_KEY *pub_key, const uint8_t **in, size_t *i return 1; } -#ifdef ENABLE_SM2_PRIVATE_KEY_EXPORT - // FIXME: side-channel of Base64 int sm2_private_key_to_pem(const SM2_KEY *a, FILE *fp) { @@ -477,7 +473,6 @@ int sm2_private_key_from_pem(SM2_KEY *a, FILE *fp) } return 1; } -#endif int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp) { diff --git a/src/sm4_xts.c b/src/sm4_xts.c index 7795bfe1c..12e805b19 100644 --- a/src/sm4_xts.c +++ b/src/sm4_xts.c @@ -92,7 +92,7 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea for (i = 0; i < nblocks - 2; i++) { gmssl_memxor(block, in, T, 16); - sm4_decrypt(key1, block, block); + sm4_encrypt(key1, block, block); gmssl_memxor(out, block, T, 16); gf128_from_bytes(a, T); @@ -106,7 +106,7 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea if (inlen % 16 == 0) { gmssl_memxor(block, in, T, 16); - sm4_decrypt(key1, block, block); + sm4_encrypt(key1, block, block); gmssl_memxor(out, block, T, 16); } else { @@ -117,7 +117,7 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea gf128_to_bytes(a, T1); gmssl_memxor(block, in, T1, 16); - sm4_decrypt(key1, block, block); + sm4_encrypt(key1, block, block); gmssl_memxor(block, block, T1, 16); in += 16; @@ -127,7 +127,7 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea memcpy(block, in, inlen); gmssl_memxor(block, block, T, 16); - sm4_decrypt(key1, block, block); + sm4_encrypt(key1, block, block); gmssl_memxor(out, block, T, 16); } diff --git a/tests/rdrandtest.c b/tests/rdrandtest.c new file mode 100644 index 000000000..b57e76e9e --- /dev/null +++ b/tests/rdrandtest.c @@ -0,0 +1,63 @@ +/* + * Copyright 2014-2024 The GmSSL Project. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + +#include +#include +#include +#include +#include + + +int test_rdrand(void) +{ + const uint8_t zeros[32] = {0}; + uint8_t buf[32] = {0}; + + if (rdrand_bytes(buf, sizeof(buf)) != 1) { + error_print(); + return -1; + } + if (memcmp(buf, zeros, sizeof(zeros)) == 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int test_rdseed(void) +{ + const uint8_t zeros[32] = {0}; + uint8_t buf[32] = {0}; + + if (rdseed_bytes(buf, sizeof(buf)) != 1) { + error_print(); + return -1; + } + if (memcmp(buf, zeros, sizeof(zeros)) == 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_rdrand() != 1) goto err; + if (test_rdseed() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/sm4_cbctest.c b/tests/sm4_cbctest.c new file mode 100644 index 000000000..bbacf921c --- /dev/null +++ b/tests/sm4_cbctest.c @@ -0,0 +1,331 @@ +/* + * Copyright 2014-2024 The GmSSL Project. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_sm4_cbc(void) +{ + SM4_KEY sm4_key; + uint8_t key[16] = {0}; + uint8_t iv[16] = {0}; + uint8_t buf1[32] = {0}; + uint8_t buf2[32] = {0}; + uint8_t buf3[32] = {0}; + + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_encrypt(&sm4_key, iv, buf1, 2, buf2); + sm4_set_decrypt_key(&sm4_key, key); + sm4_cbc_decrypt(&sm4_key, iv, buf2, 2, buf3); + + if (memcmp(buf1, buf3, sizeof(buf3)) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_cbc_test_vectors(void) +{ + struct { + char *mode; + char *key; + char *iv; + char *plaintext; + char *ciphertext; + } tests[] = { + { + "openssl-1", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210", + "2677f46b09c122cc975533105bd4a22af6125f7275ce552c3a2bbcf533de8a3b", + }, + { + "openssl-2", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210", + "2677f46b09c122cc975533105bd4a22af6125f7275ce552c3a2bbcf533de8a3bfff5a4f208092c0901ba02d5772977369915e3fa2356c9f4eb6460ecc457e7f8e3cfa3deebfe9883e3a48bcf7c4a11aa3ec9e0d317c5d319be72a5cdddec640c", + }, + { + "openssl-3", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210", + "2677f46b09c122cc975533105bd4a22af6125f7275ce552c3a2bbcf533de8a3bfff5a4f208092c0901ba02d5772977369915e3fa2356c9f4eb6460ecc457e7f8e3cfa3deebfe9883e3a48bcf7c4a11aa3ec9e0d317c5d319be72a5cdddec640c6fc70bfa3ddaafffdd7c09b2774dcb2cec29f0c6f0b6773e985b3e395e924238505a8f120d9ca84de5c3cf7e45f097b14b3a46c5b1068669982a5c1f5f61be291b984f331d44ffb2758f771672448fc957fa1416c446427a41e25d5524a2418b9d96b2f17582f0f1aa9c204c6807f54f7b6833c5f00856659ddabc245936868c", + }, + }; + + SM4_KEY sm4_key; + uint8_t key[16]; + uint8_t iv[16]; + size_t key_len; + size_t iv_len; + uint8_t *plaintext; + size_t plaintext_len; + uint8_t *ciphertext; + size_t ciphertext_len; + uint8_t *encrypted; + size_t encrypted_len; + size_t i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + + if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) { + error_print(); + return -1; + } + if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) { + error_print(); + return -1; + } + hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len); + hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len); + + if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) { + error_print(); + return -1; + } + + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_encrypt(&sm4_key, iv, plaintext, plaintext_len/16, encrypted); + + if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) { + error_print(); + return -1; + } + + free(plaintext); + free(ciphertext); + free(encrypted); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_cbc_padding(void) +{ + SM4_KEY enc_key; + SM4_KEY dec_key; + uint8_t key[16] = {0}; + uint8_t iv[16] = {0}; + uint8_t buf1[64]; + uint8_t buf2[128]; + uint8_t buf3[128]; + size_t len1, len2, len3; + + sm4_set_encrypt_key(&enc_key, key); + sm4_set_decrypt_key(&dec_key, key); + + len1 = 0; + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + len1 = 7; + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + len1 = 16; + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + len1 = 33; + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + len1 = sizeof(buf1); + sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); + sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); + if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_cbc_ctx(void) +{ + SM4_KEY sm4_key; + SM4_CBC_CTX enc_ctx; + SM4_CBC_CTX dec_ctx; + + uint8_t key[16]; + uint8_t iv[16]; + uint8_t mbuf[16 * 10]; + uint8_t cbuf[16 * 11]; + uint8_t pbuf[16 * 11]; + size_t mlen = 0; + size_t clen = 0; + size_t plen = 0; + + uint8_t *in; + uint8_t *out; + size_t len; + size_t lens[] = { 1,5,17,80 }; + int i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + + + // first test + + mlen = 16; + rand_bytes(mbuf, mlen); + + if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1 + || sm4_cbc_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 + || sm4_cbc_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertext + sm4_set_encrypt_key(&sm4_key, key); + sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen); + if (clen != plen || memcmp(cbuf, pbuf, plen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1 + || sm4_cbc_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 + || sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { + error_print(); + return -1; + } + plen += len; + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + + // second test + + rand_bytes(mbuf, sizeof(mbuf)); + + if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1) { + error_print(); + return -1; + } + in = mbuf; + out = cbuf; + mlen = 0; + clen = 0; + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + if (sm4_cbc_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) { + error_print(); + return -1; + } + in += lens[i]; + mlen += lens[i]; + out += len; + clen += len; + + } + if (sm4_cbc_encrypt_finish(&enc_ctx, out, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertest + sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen); + if (plen != clen || memcmp(pbuf, cbuf, clen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1) { + error_print(); + return -1; + } + plen = 0; + in = cbuf; + out = pbuf; + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + if (sm4_cbc_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) { + error_print(); + return -1; + } + in += lens[i]; + clen -= lens[i]; + out += len; + plen += len; + } + if (sm4_cbc_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) { + error_print(); + return -1; + } + out += len; + plen += len; + if (sm4_cbc_decrypt_finish(&dec_ctx, out, &len) != 1) { + error_print(); + return -1; + } + plen += len; + + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_sm4_cbc() != 1) goto err; + if (test_sm4_cbc_test_vectors() != 1) goto err; + if (test_sm4_cbc_padding() != 1) goto err; + if (test_sm4_cbc_ctx() != 1) goto err; + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/sm4_ccmtest.c b/tests/sm4_ccmtest.c index ce66f2274..fefddce22 100644 --- a/tests/sm4_ccmtest.c +++ b/tests/sm4_ccmtest.c @@ -65,9 +65,121 @@ static int test_sm4_ccm(void) return 1; } +static int test_sm4_ccm_test_vectors(void) +{ + struct { + char *label; + char *key; + char *iv; + char *aad; + char *tag; + char *plaintext; + char *ciphertext; + } tests[] = { + { + "rfc8998", + "0123456789abcdeffedcba9876543210", + "00001234567800000000abcd", + "feedfacedeadbeeffeedfacedeadbeefabaddad2", + "16842d4fa186f56ab33256971fa110f4", + "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa", + "48af93501fa62adbcd414cce6034d895dda1bf8f132f042098661572e7483094fd12e518ce062c98acee28d95df4416bed31a2f04476c18bb40c84a74b97dc5b", + }, + }; + + uint8_t key[16]; + size_t key_len; + uint8_t iv[16]; + size_t iv_len; + uint8_t *aad; + size_t aad_len; + uint8_t tag[16]; + size_t tag_len; + uint8_t *plaintext; + size_t plaintext_len; + uint8_t *ciphertext; + size_t ciphertext_len; + + SM4_KEY sm4_key; + uint8_t *encrypted; + size_t encrypted_len; + uint8_t *decrypted; + size_t decrypted_len; + uint8_t mac[16]; + size_t i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + + if ((aad = (uint8_t *)malloc(strlen(tests[i].aad)/2)) == NULL) { + error_print(); + return -1; + } + if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) { + error_print(); + return -1; + } + if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) { + error_print(); + return -1; + } + + hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + hex_to_bytes(tests[i].aad, strlen(tests[i].aad), aad, &aad_len); + hex_to_bytes(tests[i].tag, strlen(tests[i].tag), tag, &tag_len); + hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len); + hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len); + + if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) { + error_print(); + return -1; + } + if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) { + error_print(); + return -1; + } + + sm4_set_encrypt_key(&sm4_key, key); + if (sm4_ccm_encrypt(&sm4_key, iv, iv_len, aad, aad_len, + plaintext, plaintext_len, encrypted, tag_len, mac) != 1) { + error_print(); + return -1; + } + if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) { + error_print(); + return -1; + } + if (memcmp(mac, tag, tag_len) != 0) { + error_print(); + return -1; + } + + //sm4_set_encrypt_key(&sm4_key, key); // same as ccm_encrypt + if (sm4_ccm_decrypt(&sm4_key, iv, iv_len, aad, aad_len, + ciphertext, ciphertext_len, tag, tag_len, decrypted) != 1) { + error_print(); + return -1; + } + if (memcmp(decrypted, plaintext, plaintext_len) != 0) { + error_print(); + return -1; + } + + free(aad); + free(plaintext); + free(ciphertext); + free(encrypted); + free(decrypted); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + int main(void) { if (test_sm4_ccm() != 1) goto err; + if (test_sm4_ccm_test_vectors() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0; err: diff --git a/tests/sm4_cfbtest.c b/tests/sm4_cfbtest.c index 8e031e375..26980d474 100644 --- a/tests/sm4_cfbtest.c +++ b/tests/sm4_cfbtest.c @@ -59,6 +59,113 @@ static int test_sm4_cfb(void) return 1; } +// FIXME: no test vectors for SM4_CFB_8, SM4_CFB_64 +static int test_sm4_cfb_test_vectors(void) +{ + struct { + char *label; + char *key; + size_t sbytes; + char *iv; + char *plaintext; + char *ciphertext; + } tests[] = { + { + "openssl", + "0123456789abcdeffedcba9876543210", + SM4_CFB_128, + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210", + "693d9a535bad5bb1786f53d7253a70569ed258a85a0467cc92aab393dd978995", + }, + { + "draft-ribose-cfrg-sm4-10 example-1", + "0123456789abcdeffedcba9876543210", + SM4_CFB_128, + "000102030405060708090a0b0c0d0e0f", + "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffaaaaaaaabbbbbbbb", + "ac3236cb861dd316e6413b4e3c7524b769d4c54ed433b9a0346009beb37b2b3f", + }, + { + "draft-ribose-cfrg-sm4-10 example-2", + "fedcba98765432100123456789abcdef", + SM4_CFB_128, + "000102030405060708090a0b0c0d0e0f", + "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffaaaaaaaabbbbbbbb", + "5dcccd25a84ba16560d7f265887068490d9b86ff20c3bfe115ffa02ca6192cc5" + }, + }; + + uint8_t key[16]; + size_t key_len; + uint8_t iv[16]; + size_t iv_len; + uint8_t *plaintext; + size_t plaintext_len; + uint8_t *ciphertext; + size_t ciphertext_len; + + SM4_KEY sm4_key; + uint8_t *encrypted; + size_t encrypted_len; + uint8_t *decrypted; + size_t decrypted_len; + size_t i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + + + if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) { + error_print(); + return -1; + } + if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) { + error_print(); + return -1; + } + + hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len); + hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len); + + if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) { + error_print(); + return -1; + } + + sm4_set_encrypt_key(&sm4_key, key); + sm4_cfb_encrypt(&sm4_key, tests[i].sbytes, iv, plaintext, plaintext_len, encrypted); + + if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) { + error_print(); + return -1; + } + + if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) { + error_print(); + return -1; + } + + //sm4_set_encrypt_key(&sm4_key, key); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + sm4_cfb_decrypt(&sm4_key, tests[i].sbytes, iv, ciphertext, ciphertext_len, decrypted); + + if (memcmp(decrypted, plaintext, plaintext_len) != 0) { + error_print(); + return -1; + } + + free(plaintext); + free(ciphertext); + free(encrypted); + free(decrypted); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + static int test_sm4_cfb_ctx(void) { @@ -158,6 +265,7 @@ static int test_sm4_cfb_ctx(void) int main(void) { if (test_sm4_cfb() != 1) goto err; + if (test_sm4_cfb_test_vectors() != 1) goto err; if (test_sm4_cfb_ctx() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0; diff --git a/tests/sm4_ctrtest.c b/tests/sm4_ctrtest.c new file mode 100644 index 000000000..73b4bfc1e --- /dev/null +++ b/tests/sm4_ctrtest.c @@ -0,0 +1,373 @@ +/* + * Copyright 2014-2024 The GmSSL Project. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the License); you may + * not use this file except in compliance with the License. + * + * http://www.apache.org/licenses/LICENSE-2.0 + */ + + +#include +#include +#include +#include +#include +#include +#include +#include + + +static int test_sm4_ctr(void) +{ + SM4_KEY sm4_key; + uint8_t key[16] = {0}; + uint8_t ctr[16]; + uint8_t buf1[30] = {0}; + uint8_t buf2[30] = {0}; + uint8_t buf3[30] = {0}; + + sm4_set_encrypt_key(&sm4_key, key); + memset(ctr, 0, sizeof(ctr)); + sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2); + + memset(ctr, 0, sizeof(ctr)); + sm4_ctr_encrypt(&sm4_key, ctr, buf2, sizeof(buf2), buf3); + + if (memcmp(buf1, buf3, sizeof(buf3)) != 0) { + fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_ctr_test_vectors(void) +{ + struct { + char *label; + char *key; + char *iv; + char *plaintext; + char *ciphertext; + } tests[] = { + { + "openssl-1", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba9876543210", + "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa", + "c2b4759e78ac3cf43d0852f4e8d5f9fd7256e8a5fcb65a350ee00630912e44492a0b17e1b85b060d0fba612d8a95831638b361fd5ffacd942f081485a83ca35d", + }, + { + "draft-ribose-cfrg-sm4-10 example-1", + "0123456789abcdeffedcba9876543210", + "000102030405060708090a0b0c0d0e0f", + "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb", + "ac3236cb970cc20791364c395a1342d1a3cbc1878c6f30cd074cce385cdd70c7f234bc0e24c11980fd1286310ce37b926e02fcd0faa0baf38b2933851d824514", + }, + { + "draft-ribose-cfrg-sm4-10 example-2", + "fedcba98765432100123456789abcdef", + "000102030405060708090a0b0c0d0e0f", + "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb", + "5dcccd25b95ab07417a08512ee160e2f8f661521cbbab44cc87138445bc29e5c0ae0297205d62704173b21239b887f6c8cb5b800917a2488284bde9e16ea2906", + }, + }; + + uint8_t key[16]; + size_t key_len; + uint8_t iv[16]; + size_t iv_len; + uint8_t *plaintext; + size_t plaintext_len; + uint8_t *ciphertext; + size_t ciphertext_len; + + SM4_KEY sm4_key; + uint8_t *encrypted; + size_t encrypted_len; + uint8_t *decrypted; + size_t decrypted_len; + size_t i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + + if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) { + error_print(); + return -1; + } + if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) { + error_print(); + return -1; + } + + hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len); + hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len); + + if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) { + error_print(); + return -1; + } + if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) { + error_print(); + return -1; + } + + sm4_set_encrypt_key(&sm4_key, key); + sm4_ctr_encrypt(&sm4_key, iv, plaintext, plaintext_len, encrypted); + + if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) { + error_print(); + return -1; + } + + //sm4_set_encrypt_key(&sm4_key, key); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + sm4_ctr_encrypt(&sm4_key, iv, ciphertext, ciphertext_len, decrypted); + + if (memcmp(decrypted, plaintext, plaintext_len) != 0) { + error_print(); + return -1; + } + + free(plaintext); + free(ciphertext); + free(encrypted); + free(decrypted); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_ctr_with_carray(void) +{ + const char *hex_key = "0123456789ABCDEFFEDCBA9876543210"; + const char *hex_ctr = "0000000000000000000000000000FFFF"; + const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB" + "CCCCCCCCCCCCCCCCDDDDDDDDDDDD"; + const char *hex_out = "7EA678F9F0CBE2000917C63D4E77B4C8" + "6E4E8532B0046E4AC1E97DA8B831"; + + SM4_KEY sm4_key; + uint8_t key[16] = {0}; + uint8_t ctr[16]; + uint8_t buf1[30] = {0}; + uint8_t buf2[30] = {0}; + uint8_t buf3[30] = {0}; + + size_t keylen, ctrlen, inlen, outlen; + + hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); + hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); + hex_to_bytes(hex_in, strlen(hex_in), buf1, &inlen); + hex_to_bytes(hex_out, strlen(hex_out), buf3, &outlen); + + sm4_set_encrypt_key(&sm4_key, key); + + sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2); + + if (memcmp(buf2, buf3, sizeof(buf3)) != 0) { + error_print(); + return -1; + } + + hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); + sm4_ctr_encrypt(&sm4_key, ctr, buf3, sizeof(buf3), buf2); + + if (memcmp(buf2, buf1, sizeof(buf1)) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +/* + * NOTE: + * There is an compiler bug on Tencent Cloud/Windows Server 2022/Visual Studio 2022 and GitHub CI Windows env. + * When calling memcpy(ctr, iv, sizeof(iv)) multiple times. The compiler might omit the memcpy() + * As `ctr` has been changed by sm4_ctr_encrypt() and the reset to `iv` is not working, the test will fail. + */ +static int test_sm4_ctr_ctx(void) +{ + SM4_KEY sm4_key; + SM4_CTR_CTX enc_ctx; + SM4_CTR_CTX dec_ctx; + + uint8_t key[16]; + uint8_t iv[16]; + uint8_t ctr[16]; + uint8_t mbuf[16]; + uint8_t cbuf[16]; + uint8_t pbuf[32]; + size_t mlen = 0; + size_t clen = 0; + size_t plen = 0; + size_t len; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + mlen = sizeof(mbuf); + rand_bytes(mbuf, mlen); + + if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1 + || sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 + || sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertext + sm4_set_encrypt_key(&sm4_key, key); + memcpy(ctr, iv, sizeof(iv)); // ctr is a variable + sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // NOTE: sm4_ctr_encrypt() change ctr value + + if (memcmp(cbuf, pbuf, clen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1 + || sm4_ctr_encrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 + || sm4_ctr_encrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { + error_print(); + return -1; + } + plen += len; + + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_ctr_ctx_multi_updates(void) +{ + SM4_KEY sm4_key; + SM4_CTR_CTX enc_ctx; + SM4_CTR_CTX dec_ctx; + + uint8_t key[16]; + uint8_t iv[16]; + uint8_t ctr[16]; + uint8_t mbuf[16 * 10]; + uint8_t cbuf[16 * 11]; + uint8_t pbuf[16 * 11]; + size_t mlen = 0; + size_t clen = 0; + size_t plen = 0; + + uint8_t *in; + uint8_t *out; + size_t len; + size_t lens[] = { 1,5,17,80 }; + + int i; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + rand_bytes(mbuf, sizeof(mbuf)); + + if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1) { + error_print(); + return -1; + } + in = mbuf; + out = cbuf; + mlen = 0; + clen = 0; + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + if (sm4_ctr_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) { + error_print(); + return -1; + } + in += lens[i]; + mlen += lens[i]; + if (mlen > sizeof(mbuf)) { + // invalid lens[] values, reset the test data + error_print(); + return -1; + } + out += len; + clen += len; + } + if (sm4_ctr_encrypt_finish(&enc_ctx, out, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertest + sm4_set_encrypt_key(&sm4_key, key); + memcpy(ctr, iv, sizeof(iv)); + sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); + if (memcmp(pbuf, cbuf, mlen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1) { + error_print(); + return -1; + } + plen = 0; + in = cbuf; + out = pbuf; + for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { + if (sm4_ctr_encrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) { + error_print(); + return -1; + } + in += lens[i]; + clen -= lens[i]; + out += len; + plen += len; + } + if (sm4_ctr_encrypt_update(&dec_ctx, in, clen, out, &len) != 1) { + error_print(); + return -1; + } + out += len; + plen += len; + if (sm4_ctr_encrypt_finish(&dec_ctx, out, &len) != 1) { + error_print(); + return -1; + } + plen += len; + + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + if (test_sm4_ctr() != 1) goto err; + if (test_sm4_ctr_test_vectors() != 1) goto err; + if (test_sm4_ctr_with_carray() != 1) goto err; + if (test_sm4_ctr_ctx() != 1) goto err; + if (test_sm4_ctr_ctx_multi_updates() != 1) goto err; + + printf("%s all tests passed\n", __FILE__); + return 0; +err: + error_print(); + return 1; +} diff --git a/tests/sm4_ecbtest.c b/tests/sm4_ecbtest.c index 75468d5b1..6b05308f8 100644 --- a/tests/sm4_ecbtest.c +++ b/tests/sm4_ecbtest.c @@ -47,7 +47,7 @@ static int test_sm4_ecb(void) return 1; } -static int test_sm4_ecb_testvec(void) +static int test_sm4_ecb_test_vectors(void) { SM4_KEY sm4_key; uint8_t key[16] = { @@ -180,11 +180,10 @@ static int test_sm4_ecb_ctx(void) return 1; } - int main(void) { if (test_sm4_ecb() != 1) goto err; - if (test_sm4_ecb_testvec() != 1) goto err; + if (test_sm4_ecb_test_vectors() != 1) goto err; if (test_sm4_ecb_ctx() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0; diff --git a/tests/sm4_gcmtest.c b/tests/sm4_gcmtest.c index 429d682bb..4d7bee7b1 100644 --- a/tests/sm4_gcmtest.c +++ b/tests/sm4_gcmtest.c @@ -196,7 +196,7 @@ static int test_sm4_gcm_gbt36624_2(void) return 1; } -static int test_sm4_gcm_update(void) +static int test_sm4_gcm_ctx(void) { SM4_GCM_CTX aead_ctx; uint8_t key[16]; @@ -317,7 +317,7 @@ int main(void) if (test_sm4_gcm() != 1) goto err; if (test_sm4_gcm_gbt36624_1() != 1) goto err; if (test_sm4_gcm_gbt36624_2() != 1) goto err; - if (test_sm4_gcm_update() != 1) goto err; + if (test_sm4_gcm_ctx() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0; err: diff --git a/tests/sm4_ofbtest.c b/tests/sm4_ofbtest.c index 8698d8998..2d673ec69 100644 --- a/tests/sm4_ofbtest.c +++ b/tests/sm4_ofbtest.c @@ -55,6 +55,107 @@ static int test_sm4_ofb(void) return 1; } +static int test_sm4_ofb_test_vectors(void) +{ + struct { + char *label; + char *key; + char *iv; + char *plaintext; + char *ciphertext; + } tests[] = { + { + "sm4-ofb from openssl", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba9876543210", + "0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210", + "693d9a535bad5bb1786f53d7253a7056f2075d28b5235f58d50027e4177d2bce", + }, + { + "sm4-ofb-example-1 from draft-ribose-cfrg-sm4-10", + "0123456789abcdeffedcba9876543210", + "000102030405060708090a0b0c0d0e0f", + "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffaaaaaaaabbbbbbbb", + "ac3236cb861dd316e6413b4e3c7524b71d01aca2487ca582cbf5463e6698539b", + }, + { + "sm4-ofb-example-2 from draft-ribose-cfrg-sm4-10", + "fedcba98765432100123456789abcdef", + "000102030405060708090a0b0c0d0e0f", + "aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffaaaaaaaabbbbbbbb", + "5dcccd25a84ba16560d7f2658870684933fa16bd5cd9c856cacaa1e101897a97", + }, + }; + + uint8_t key[16]; + size_t key_len; + uint8_t iv[16]; + size_t iv_len; + uint8_t *plaintext; + size_t plaintext_len; + uint8_t *ciphertext; + size_t ciphertext_len; + + SM4_KEY sm4_key; + uint8_t *encrypted; + size_t encrypted_len; + uint8_t *decrypted; + size_t decrypted_len; + size_t i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + + + if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) { + error_print(); + return -1; + } + if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) { + error_print(); + return -1; + } + + hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len); + hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len); + + if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) { + error_print(); + return -1; + } + if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) { + error_print(); + return -1; + } + + sm4_set_encrypt_key(&sm4_key, key); + sm4_ofb_encrypt(&sm4_key, iv, plaintext, plaintext_len, encrypted); + + if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) { + error_print(); + return -1; + } + + sm4_set_encrypt_key(&sm4_key, key); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + sm4_ofb_encrypt(&sm4_key, iv, ciphertext, ciphertext_len, decrypted); + + if (memcmp(decrypted, plaintext, plaintext_len) != 0) { + error_print(); + return -1; + } + + free(plaintext); + free(ciphertext); + free(encrypted); + free(decrypted); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + static int test_sm4_ofb_ctx(void) { SM4_OFB_CTX ctx; @@ -150,6 +251,7 @@ static int test_sm4_ofb_ctx(void) int main(void) { if (test_sm4_ofb() != 1) goto err; + if (test_sm4_ofb_test_vectors() != 1) goto err; if (test_sm4_ofb_ctx() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0; diff --git a/tests/sm4_xtstest.c b/tests/sm4_xtstest.c index 378e19b8d..4fe8b88b0 100644 --- a/tests/sm4_xtstest.c +++ b/tests/sm4_xtstest.c @@ -54,9 +54,118 @@ static int test_sm4_xts(void) return 1; } +static int test_sm4_xts_test_vectors(void) +{ + struct { + char *label; + char *key; + char *iv; + char *plaintext; + char *ciphertext; + } tests[] = { + { + "https://github.com/mewmix/sm4-xts-openssl", + "68d90424687cc2043595091a78a44ec2c639c3ecc6b14d7ac42ce74e582fa3dc", + "601cd97ddeb1c75bbe5865072f3dc7a8", + "686579667269656e64736c657473676574656e6372797074656421", + "34143fbf6cb3a97feb84f866d85e01f8d15ed03905552cb12cd567", + }, + { + "openssl-1 (openssl/test/recipes/30-test_evp_data/evpciph_sm4.txt)", + "2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f", + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17", + "e9538251c71d7b80bbe4483fef497bd12c5c581bd6242fc51e08964fb4f60fdb0ba42f63499279213d318d2c11f6886e903be7f93a1b3479", + }, + { + "openssl-2", + "2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f", + "f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff", + "6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17", + "e9538251c71d7b80bbe4483fef497bd12c5c581bd6242fc51e08964fb4f60fdb0ba42f63499279213d318d2c11f6886e903be7f93a1b3479", + }, + }; + + SM4_KEY sm4_key1; + SM4_KEY sm4_key2; + + uint8_t key[32]; + size_t key_len; + uint8_t iv[16]; + size_t iv_len; + uint8_t *aad; + size_t aad_len; + uint8_t tag[16]; + size_t tag_len; + uint8_t *plaintext; + size_t plaintext_len; + uint8_t *ciphertext; + size_t ciphertext_len; + + uint8_t *encrypted; + size_t encrypted_len; + uint8_t *decrypted; + size_t decrypted_len; + size_t i; + + for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) { + + if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) { + error_print(); + return -1; + } + if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) { + error_print(); + return -1; + } + + hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len); + hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len); + hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len); + hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len); + + if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) { + error_print(); + return -1; + } + if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) { + error_print(); + return -1; + } + + sm4_set_encrypt_key(&sm4_key1, key); + sm4_set_encrypt_key(&sm4_key2, key + 16); + + if (sm4_xts_encrypt(&sm4_key1, &sm4_key2, iv, plaintext, plaintext_len, encrypted) != 1) { + error_print(); + return -1; + } + if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) { + error_print(); + return -1; + } + + sm4_set_decrypt_key(&sm4_key1, key); + sm4_set_encrypt_key(&sm4_key2, key + 16); + if (sm4_xts_decrypt(&sm4_key1, &sm4_key2, iv, ciphertext, ciphertext_len, decrypted) != 1) { + error_print(); + return -1; + } + + free(plaintext); + free(ciphertext); + free(encrypted); + free(decrypted); + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + int main(void) { if (test_sm4_xts() != 1) goto err; + if (test_sm4_xts_test_vectors() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0; err: diff --git a/tests/sm4test.c b/tests/sm4test.c index fb455d115..b3d1065eb 100644 --- a/tests/sm4test.c +++ b/tests/sm4test.c @@ -90,648 +90,24 @@ static int test_sm4(void) return 1; } -static int test_sm4_cbc(void) -{ - SM4_KEY sm4_key; - uint8_t key[16] = {0}; - uint8_t iv[16] = {0}; - uint8_t buf1[32] = {0}; - uint8_t buf2[32] = {0}; - uint8_t buf3[32] = {0}; - - sm4_set_encrypt_key(&sm4_key, key); - sm4_cbc_encrypt(&sm4_key, iv, buf1, 2, buf2); - sm4_set_decrypt_key(&sm4_key, key); - sm4_cbc_decrypt(&sm4_key, iv, buf2, 2, buf3); - - if (memcmp(buf1, buf3, sizeof(buf3)) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_cbc_padding(void) -{ - SM4_KEY enc_key; - SM4_KEY dec_key; - uint8_t key[16] = {0}; - uint8_t iv[16] = {0}; - uint8_t buf1[64]; - uint8_t buf2[128]; - uint8_t buf3[128]; - size_t len1, len2, len3; - - sm4_set_encrypt_key(&enc_key, key); - sm4_set_decrypt_key(&dec_key, key); - - len1 = 0; - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - len1 = 7; - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - len1 = 16; - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - len1 = 33; - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - len1 = sizeof(buf1); - sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2); - sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3); - if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_ctr(void) -{ - SM4_KEY sm4_key; - uint8_t key[16] = {0}; - uint8_t ctr[16]; - uint8_t buf1[30] = {0}; - uint8_t buf2[30] = {0}; - uint8_t buf3[30] = {0}; - - sm4_set_encrypt_key(&sm4_key, key); - memset(ctr, 0, sizeof(ctr)); - sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2); - - memset(ctr, 0, sizeof(ctr)); - sm4_ctr_encrypt(&sm4_key, ctr, buf2, sizeof(buf2), buf3); - - if (memcmp(buf1, buf3, sizeof(buf3)) != 0) { - fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_ctr_with_carray(void) -{ - const char *hex_key = "0123456789ABCDEFFEDCBA9876543210"; - const char *hex_ctr = "0000000000000000000000000000FFFF"; - const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB" - "CCCCCCCCCCCCCCCCDDDDDDDDDDDD"; - const char *hex_out = "7EA678F9F0CBE2000917C63D4E77B4C8" - "6E4E8532B0046E4AC1E97DA8B831"; - SM4_KEY sm4_key; - uint8_t key[16] = {0}; - uint8_t ctr[16]; - uint8_t buf1[30] = {0}; - uint8_t buf2[30] = {0}; - uint8_t buf3[30] = {0}; - size_t keylen, ctrlen, inlen, outlen; - - hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); - hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); - hex_to_bytes(hex_in, strlen(hex_in), buf1, &inlen); - hex_to_bytes(hex_out, strlen(hex_out), buf3, &outlen); - - sm4_set_encrypt_key(&sm4_key, key); - - sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2); - - if (memcmp(buf2, buf3, sizeof(buf3)) != 0) { - error_print(); - return -1; - } - - hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen); - sm4_ctr_encrypt(&sm4_key, ctr, buf3, sizeof(buf3), buf2); - - if (memcmp(buf2, buf1, sizeof(buf1)) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_gcm(void) -{ - // gcm test vectors from rfc 8998 A.1 - const char *hex_key = "0123456789ABCDEFFEDCBA9876543210"; - const char *hex_iv = "00001234567800000000ABCD"; - const char *hex_aad = "FEEDFACEDEADBEEFFEEDFACEDEADBEEF" - "ABADDAD2"; - const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB" - "CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD" - "EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF" - "EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA"; - const char *hex_out = "17F399F08C67D5EE19D0DC9969C4BB7D" - "5FD46FD3756489069157B282BB200735" - "D82710CA5C22F0CCFA7CBF93D496AC15" - "A56834CBCF98C397B4024A2691233B8D"; - const char *hex_tag = "83DE3541E4C2B58177E065A9BF7B62EC"; - - SM4_KEY sm4_key; - uint8_t key[16]; - uint8_t iv[12]; - uint8_t aad[20]; - uint8_t in[64]; - uint8_t out[64]; - uint8_t tag[16]; - size_t keylen, ivlen, aadlen, inlen, outlen, taglen; - - uint8_t buf[64]; - uint8_t mac[16]; - - hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); - hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen); - hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen); - hex_to_bytes(hex_in, strlen(hex_in), in, &inlen); - hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); - hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen); - - memset(buf, 0, sizeof(buf)); - memset(mac, 0, sizeof(mac)); - - sm4_set_encrypt_key(&sm4_key, key); - - // test gcm encrypt - sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac); - if (memcmp(buf, out, outlen) != 0) { - error_print(); - return -1; - } - if (memcmp(mac, tag, taglen) != 0) { - error_print(); - return -1; - } - - // test gcm decrypt - memset(buf, 0, sizeof(buf)); - sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf); - if (memcmp(buf, in, inlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_gcm_gbt36624_1(void) -{ - // gcm test vectors from GB/T 36624-2018 C.5 - const char *hex_key = "00000000000000000000000000000000"; - const char *hex_iv = "000000000000000000000000"; - const char *hex_aad = ""; - const char *hex_in = ""; - const char *hex_out = ""; - const char *hex_tag = "232F0CFE308B49EA6FC88229B5DC858D"; - - SM4_KEY sm4_key; - uint8_t key[16]; - uint8_t iv[12]; - uint8_t aad[20]; - uint8_t in[64]; - uint8_t out[64]; - uint8_t tag[16]; - size_t keylen, ivlen, aadlen, inlen, outlen, taglen; - - uint8_t buf[64]; - uint8_t mac[16]; - - hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); - hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen); - hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen); - hex_to_bytes(hex_in, strlen(hex_in), in, &inlen); - hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); - hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen); - - memset(buf, 0, sizeof(buf)); - memset(mac, 0, sizeof(mac)); - - sm4_set_encrypt_key(&sm4_key, key); - - // test gcm encrypt - sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac); - if (memcmp(buf, out, outlen) != 0) { - error_print(); - return -1; - } - if (memcmp(mac, tag, taglen) != 0) { - error_print(); - return -1; - } - - // test gcm decrypt - memset(buf, 0, sizeof(buf)); - sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf); - if (memcmp(buf, in, inlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_gcm_gbt36624_2(void) -{ - // gcm test vectors from GB/T 36624-2018 C.5 - const char *hex_key = "00000000000000000000000000000000"; - const char *hex_iv = "000000000000000000000000"; - const char *hex_aad = ""; - const char *hex_in = "00000000000000000000000000000000"; - const char *hex_out = "7DE2AA7F1110188218063BE1BFEB6D89"; - const char *hex_tag = "B851B5F39493752BE508F1BB4482C557"; - - SM4_KEY sm4_key; - uint8_t key[16]; - uint8_t iv[12]; - uint8_t aad[20]; - uint8_t in[64]; - uint8_t out[64]; - uint8_t tag[16]; - size_t keylen, ivlen, aadlen, inlen, outlen, taglen; - - uint8_t buf[64]; - uint8_t mac[16]; - - hex_to_bytes(hex_key, strlen(hex_key), key, &keylen); - hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen); - hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen); - hex_to_bytes(hex_in, strlen(hex_in), in, &inlen); - hex_to_bytes(hex_out, strlen(hex_out), out, &outlen); - hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen); - - memset(buf, 0, sizeof(buf)); - memset(mac, 0, sizeof(mac)); - - sm4_set_encrypt_key(&sm4_key, key); - - // test gcm encrypt - sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac); - if (memcmp(buf, out, outlen) != 0) { - error_print(); - return -1; - } - if (memcmp(mac, tag, taglen) != 0) { - error_print(); - return -1; - } - - // test gcm decrypt - memset(buf, 0, sizeof(buf)); - sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf); - if (memcmp(buf, in, inlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_cbc_update(void) -{ - SM4_KEY sm4_key; - SM4_CBC_CTX enc_ctx; - SM4_CBC_CTX dec_ctx; - - uint8_t key[16]; - uint8_t iv[16]; - uint8_t mbuf[16 * 10]; - uint8_t cbuf[16 * 11]; - uint8_t pbuf[16 * 11]; - size_t mlen = 0; - size_t clen = 0; - size_t plen = 0; - - uint8_t *in; - uint8_t *out; - size_t len; - size_t lens[] = { 1,5,17,80 }; - int i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - - - // first test - - mlen = 16; - rand_bytes(mbuf, mlen); - - if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1 - || sm4_cbc_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 - || sm4_cbc_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertext - sm4_set_encrypt_key(&sm4_key, key); - sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen); - if (clen != plen || memcmp(cbuf, pbuf, plen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1 - || sm4_cbc_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 - || sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { - error_print(); - return -1; - } - plen += len; - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - - // second test - - rand_bytes(mbuf, sizeof(mbuf)); - - if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1) { - error_print(); - return -1; - } - in = mbuf; - out = cbuf; - mlen = 0; - clen = 0; - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - if (sm4_cbc_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) { - error_print(); - return -1; - } - in += lens[i]; - mlen += lens[i]; - out += len; - clen += len; - - } - if (sm4_cbc_encrypt_finish(&enc_ctx, out, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertest - sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen); - if (plen != clen || memcmp(pbuf, cbuf, clen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1) { - error_print(); - return -1; - } - plen = 0; - in = cbuf; - out = pbuf; - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - if (sm4_cbc_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) { - error_print(); - return -1; - } - in += lens[i]; - clen -= lens[i]; - out += len; - plen += len; - } - if (sm4_cbc_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) { - error_print(); - return -1; - } - out += len; - plen += len; - if (sm4_cbc_decrypt_finish(&dec_ctx, out, &len) != 1) { - error_print(); - return -1; - } - plen += len; - - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -/* - * NOTE: - * There is an compiler bug on Tencent Cloud/Windows Server 2022/Visual Studio 2022 and GitHub CI Windows env. - * When calling memcpy(ctr, iv, sizeof(iv)) multiple times. The compiler might omit the memcpy() - * As `ctr` has been changed by sm4_ctr_encrypt() and the reset to `iv` is not working, the test will fail. - */ -static int test_sm4_ctr_update_once(void) -{ - SM4_KEY sm4_key; - SM4_CTR_CTX enc_ctx; - SM4_CTR_CTX dec_ctx; - - uint8_t key[16]; - uint8_t iv[16]; - uint8_t ctr[16]; - uint8_t mbuf[16]; - uint8_t cbuf[16]; - uint8_t pbuf[32]; - size_t mlen = 0; - size_t clen = 0; - size_t plen = 0; - size_t len; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - mlen = sizeof(mbuf); - rand_bytes(mbuf, mlen); - - if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1 - || sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 - || sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertext - sm4_set_encrypt_key(&sm4_key, key); - memcpy(ctr, iv, sizeof(iv)); // ctr is a variable - sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // NOTE: sm4_ctr_encrypt() change ctr value - - if (memcmp(cbuf, pbuf, clen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1 - || sm4_ctr_encrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 - || sm4_ctr_encrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { - error_print(); - return -1; - } - plen += len; - - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_sm4_ctr_update_multi_times(void) -{ - SM4_KEY sm4_key; - SM4_CTR_CTX enc_ctx; - SM4_CTR_CTX dec_ctx; - - uint8_t key[16]; - uint8_t iv[16]; - uint8_t ctr[16]; - uint8_t mbuf[16 * 10]; - uint8_t cbuf[16 * 11]; - uint8_t pbuf[16 * 11]; - size_t mlen = 0; - size_t clen = 0; - size_t plen = 0; - - uint8_t *in; - uint8_t *out; - size_t len; - size_t lens[] = { 1,5,17,80 }; - - int i; - - rand_bytes(key, sizeof(key)); - rand_bytes(iv, sizeof(iv)); - - rand_bytes(mbuf, sizeof(mbuf)); - - if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1) { - error_print(); - return -1; - } - in = mbuf; - out = cbuf; - mlen = 0; - clen = 0; - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - if (sm4_ctr_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) { - error_print(); - return -1; - } - in += lens[i]; - mlen += lens[i]; - assert(mlen <= sizeof(mbuf)); - out += len; - clen += len; - } - if (sm4_ctr_encrypt_finish(&enc_ctx, out, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertest - sm4_set_encrypt_key(&sm4_key, key); - memcpy(ctr, iv, sizeof(iv)); - sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); - if (memcmp(pbuf, cbuf, mlen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1) { - error_print(); - return -1; - } - plen = 0; - in = cbuf; - out = pbuf; - for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) { - if (sm4_ctr_encrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) { - error_print(); - return -1; - } - in += lens[i]; - clen -= lens[i]; - out += len; - plen += len; - } - if (sm4_ctr_encrypt_update(&dec_ctx, in, clen, out, &len) != 1) { - error_print(); - return -1; - } - out += len; - plen += len; - if (sm4_ctr_encrypt_finish(&dec_ctx, out, &len) != 1) { - error_print(); - return -1; - } - plen += len; - - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} int main(void) { + if (test_sm4() != 1) goto err; + /* if (test_sm4_cbc() != 1) goto err; if (test_sm4_cbc_padding() != 1) goto err; - if (test_sm4_ctr() != 1) goto err; + if (test_sm4_gcm() != 1) goto err; if (test_sm4_gcm_gbt36624_1() != 1) goto err; if (test_sm4_gcm_gbt36624_2() != 1) goto err; if (test_sm4_cbc_update() != 1) goto err; - if (test_sm4_ctr_update_once() != 1) goto err; - if (test_sm4_ctr_update_multi_times() != 1) goto err; + + + */ printf("%s all tests passed\n", __FILE__); return 0; err: