diff --git a/CMakeLists.txt b/CMakeLists.txt index a45d1458..7fa94b92 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -487,9 +487,9 @@ endif() if (ENABLE_SM4_FF1) message(STATUS "ENABLE_SM4_FF1 is ON") add_definitions(-DENABLE_SM4_FF1) - list(APPEND src src/ff1.c) + list(APPEND src src/sm4_ff1.c) list(APPEND tools tools/sm4_ff1.c) - list(APPEND tests ff1) + list(APPEND tests sm4_ff1) endif() @@ -1025,7 +1025,7 @@ endif() # set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_VENDOR "GmSSL develop team") -set(CPACK_PACKAGE_VERSION "3.3.0-dev.1179") +set(CPACK_PACKAGE_VERSION "3.3.0-dev.1180") set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_NSIS_MODIFY_PATH ON) include(CPack) diff --git a/cmake/tool_sm4.cmake b/cmake/tool_sm4.cmake index 243be8a9..93bac563 100644 --- a/cmake/tool_sm4.cmake +++ b/cmake/tool_sm4.cmake @@ -40,40 +40,22 @@ gmssl_run(sm4_cbc -decrypt -pkcs7_padding -key ${SM4_KEY} -iv ${SM4_IV} -in tool_sm4_cbc_pkcs7_kat.cipher -out tool_sm4_cbc_pkcs7_kat.decrypt) gmssl_files_equal(tool_sm4_cbc_pkcs7_kat.plain tool_sm4_cbc_pkcs7_kat.decrypt) -file(WRITE tool_sm4_unified_cbc_kat.plain "0123456789abcdef") -gmssl_run(sm4 -cbc -encrypt -key ${SM4_KEY} -iv ${SM4_IV} - -in tool_sm4_unified_cbc_kat.plain -out tool_sm4_unified_cbc_kat.cipher) -gmssl_expect_file_hex(tool_sm4_unified_cbc_kat.cipher - "e6887b77dbabb572ffa07fed7548b192ceaace11f2b90b94c2b7a4d9382e471e") -gmssl_run(sm4 -cbc -decrypt -key ${SM4_KEY} -iv ${SM4_IV} - -in tool_sm4_unified_cbc_kat.cipher -out tool_sm4_unified_cbc_kat.decrypt) -gmssl_files_equal(tool_sm4_unified_cbc_kat.plain tool_sm4_unified_cbc_kat.decrypt) - gmssl_symmetric_roundtrip(tool_sm4_cbc sm4_cbc -key ${SM4_KEY} -iv ${SM4_IV}) gmssl_symmetric_roundtrip(tool_sm4_cbc_pkcs7 sm4_cbc -pkcs7_padding -key ${SM4_KEY} -iv ${SM4_IV}) gmssl_symmetric_roundtrip(tool_sm4_ctr sm4_ctr -key ${SM4_KEY} -iv ${SM4_IV}) gmssl_symmetric_roundtrip(tool_sm4_gcm sm4_gcm -key ${SM4_KEY} -iv 000000000000000000000000 -aad_hex 001122 -taglen 16) -gmssl_symmetric_roundtrip(tool_sm4_unified_cbc sm4 -cbc -key ${SM4_KEY} -iv ${SM4_IV}) -gmssl_symmetric_roundtrip(tool_sm4_unified_ctr sm4 -ctr -key ${SM4_KEY} -iv ${SM4_IV}) -gmssl_symmetric_roundtrip(tool_sm4_unified_gcm sm4 -gcm -key ${SM4_KEY} -iv 000000000000000000000000 -aad_hex 001122 -taglen 16) - if(ENABLE_SM4_ECB) gmssl_symmetric_roundtrip(tool_sm4_ecb sm4_ecb -key ${SM4_KEY}) - gmssl_symmetric_roundtrip(tool_sm4_unified_ecb sm4 -ecb -key ${SM4_KEY}) endif() if(ENABLE_SM4_CFB) gmssl_symmetric_roundtrip(tool_sm4_cfb sm4_cfb -sbytes 16 -key ${SM4_KEY} -iv ${SM4_IV}) - gmssl_symmetric_roundtrip(tool_sm4_unified_cfb sm4 -cfb -sbytes 16 -key ${SM4_KEY} -iv ${SM4_IV}) - gmssl_symmetric_roundtrip(tool_sm4_unified_cfb8 sm4 -cfb -sbytes 1 -key ${SM4_KEY} -iv ${SM4_IV}) endif() if(ENABLE_SM4_OFB) gmssl_symmetric_roundtrip(tool_sm4_ofb sm4_ofb -key ${SM4_KEY} -iv ${SM4_IV}) - gmssl_symmetric_roundtrip(tool_sm4_unified_ofb sm4 -ofb -key ${SM4_KEY} -iv ${SM4_IV}) endif() if(ENABLE_SM4_CCM) gmssl_symmetric_roundtrip(tool_sm4_ccm sm4_ccm -key ${SM4_KEY} -iv 000000000000000000000000 -aad_hex 001122 -taglen 16) - gmssl_symmetric_roundtrip(tool_sm4_unified_ccm sm4 -ccm -key ${SM4_KEY} -iv 000000000000000000000000 -aad_hex 001122 -taglen 16) endif() if(ENABLE_SM4_XTS) file(WRITE tool_sm4_xts.plain "0123456789abcdef0123456789abcdef") @@ -82,12 +64,6 @@ if(ENABLE_SM4_XTS) gmssl_run(sm4_xts -decrypt -key ${SM4_XTS_KEY} -iv ${SM4_IV} -data_unit_size 32 -in tool_sm4_xts.cipher -out tool_sm4_xts.decrypt) gmssl_files_equal(tool_sm4_xts.plain tool_sm4_xts.decrypt) - file(WRITE tool_sm4_unified_xts.plain "0123456789abcdef0123456789abcdef") - gmssl_run(sm4 -xts -encrypt -key ${SM4_XTS_KEY} -iv ${SM4_IV} -data_unit_size 32 - -in tool_sm4_unified_xts.plain -out tool_sm4_unified_xts.cipher) - gmssl_run(sm4 -xts -decrypt -key ${SM4_XTS_KEY} -iv ${SM4_IV} -data_unit_size 32 - -in tool_sm4_unified_xts.cipher -out tool_sm4_unified_xts.decrypt) - gmssl_files_equal(tool_sm4_unified_xts.plain tool_sm4_unified_xts.decrypt) endif() if(ENABLE_SM4_FF1) gmssl_expect_stdout("2326982895499381\n" diff --git a/include/gmssl/ff1.h b/include/gmssl/ff1.h deleted file mode 100644 index d48a9e8e..00000000 --- a/include/gmssl/ff1.h +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright 2014-2026 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 - */ - -#ifndef GMSSL_FF1_H -#define GMSSL_FF1_H - - -#include -#include -#include - - -#ifdef __cplusplus -extern "C" { -#endif - - -#define FF1_MIN_DIGITS 8 -#define FF1_MAX_DIGITS 18 -#define FF1_MIN_TWEAK_SIZE 0 -#define FF1_MAX_TWEAK_SIZE 11 -#define FF1_NUM_ROUNDS 10 - - -int ff1_init(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key); -int ff1_encrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, - const uint8_t *tweak, size_t tweaklen, char *out); -int ff1_decrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, - const uint8_t *tweak, size_t tweaklen, char *out); - - -#ifdef __cplusplus -} -#endif -#endif diff --git a/include/gmssl/sm4.h b/include/gmssl/sm4.h index 5e876a73..ac9f877d 100644 --- a/include/gmssl/sm4.h +++ b/include/gmssl/sm4.h @@ -1,5 +1,5 @@ /* - * Copyright 2014-2024 The GmSSL Project. All Rights Reserved. + * Copyright 2014-2026 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. @@ -259,6 +259,21 @@ int sm4_xts_decrypt_finish(SM4_XTS_CTX *ctx, uint8_t *out, size_t *outlen); #endif // ENABLE_SM4_XTS +#ifdef ENABLE_SM4_FF1 +#define SM4_FF1_MIN_DIGITS 8 +#define SM4_FF1_MAX_DIGITS 18 +#define SM4_FF1_MIN_TWEAK_SIZE 0 +#define SM4_FF1_MAX_TWEAK_SIZE 11 +#define SM4_FF1_NUM_ROUNDS 10 + +int sm4_ff1_init(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]); +int sm4_ff1_encrypt(const SM4_KEY *key, const char *in, size_t inlen, + const uint8_t *tweak, size_t tweaklen, char *out); +int sm4_ff1_decrypt(const SM4_KEY *key, const char *in, size_t inlen, + const uint8_t *tweak, size_t tweaklen, char *out); +#endif // ENABLE_SM4_FF1 + + #ifdef __cplusplus } #endif diff --git a/include/gmssl/version.h b/include/gmssl/version.h index 57bc9dac..4c720aaa 100644 --- a/include/gmssl/version.h +++ b/include/gmssl/version.h @@ -18,7 +18,7 @@ extern "C" { #define GMSSL_VERSION_NUM 30300 -#define GMSSL_VERSION_STR "GmSSL 3.3.0-dev.1179" +#define GMSSL_VERSION_STR "GmSSL 3.3.0-dev.1180" int gmssl_version_num(void); const char *gmssl_version_str(void); diff --git a/src/ff1.c b/src/sm4_ff1.c similarity index 56% rename from src/ff1.c rename to src/sm4_ff1.c index 4d573332..f9d2e015 100644 --- a/src/ff1.c +++ b/src/sm4_ff1.c @@ -7,13 +7,13 @@ * http://www.apache.org/licenses/LICENSE-2.0 */ -#include +#include #include #include #include -static const uint32_t ff1_radix10_mod[] = { +static const uint32_t sm4_ff1_radix10_mod[] = { 1, 10, 100, @@ -26,33 +26,26 @@ static const uint32_t ff1_radix10_mod[] = { 1000000000, }; -static const size_t ff1_radix10_b[] = { +static const size_t sm4_ff1_radix10_b[] = { 0, 1, 1, 2, 2, 3, 3, 3, 4, 4, }; -int ff1_init(BLOCK_CIPHER_KEY *key, const BLOCK_CIPHER *cipher, const uint8_t *raw_key) +int sm4_ff1_init(SM4_KEY *key, const uint8_t raw_key[SM4_KEY_SIZE]) { - if (!key || !cipher || !raw_key) { - error_print(); - return -1; - } - if (cipher->block_size != BLOCK_CIPHER_BLOCK_SIZE) { - error_print(); - return -1; - } - if (block_cipher_set_encrypt_key(key, cipher, raw_key) != 1) { + if (!key || !raw_key) { error_print(); return -1; } + sm4_set_encrypt_key(key, raw_key); return 1; } -static int ff1_digits_to_num(const char *digits, size_t ndigits, uint32_t *num) +static int sm4_ff1_digits_to_num(const char *digits, size_t ndigits, uint32_t *num) { uint32_t value = 0; size_t i; - if (!digits || !num || ndigits > FF1_MAX_DIGITS/2) { + if (!digits || !num || ndigits > SM4_FF1_MAX_DIGITS/2) { error_print(); return -1; } @@ -67,9 +60,9 @@ static int ff1_digits_to_num(const char *digits, size_t ndigits, uint32_t *num) return 1; } -static int ff1_num_to_digits(uint32_t num, size_t ndigits, char *digits) +static int sm4_ff1_num_to_digits(uint32_t num, size_t ndigits, char *digits) { - if (!digits || ndigits > FF1_MAX_DIGITS/2 || num >= ff1_radix10_mod[ndigits]) { + if (!digits || ndigits > SM4_FF1_MAX_DIGITS/2 || num >= sm4_ff1_radix10_mod[ndigits]) { error_print(); return -1; } @@ -80,24 +73,20 @@ static int ff1_num_to_digits(uint32_t num, size_t ndigits, char *digits) return 1; } -static int ff1_check_args(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, +static int sm4_ff1_check_args(const SM4_KEY *key, const char *in, size_t inlen, const uint8_t *tweak, size_t tweaklen, char *out) { size_t i; - if (!key || !key->cipher || !in || !out || (!tweak && tweaklen)) { + if (!key || !in || !out || (!tweak && tweaklen)) { error_print(); return -1; } - if (key->cipher->block_size != BLOCK_CIPHER_BLOCK_SIZE) { + if (inlen < SM4_FF1_MIN_DIGITS || inlen > SM4_FF1_MAX_DIGITS) { error_print(); return -1; } - if (inlen < FF1_MIN_DIGITS || inlen > FF1_MAX_DIGITS) { - error_print(); - return -1; - } - if (tweaklen < FF1_MIN_TWEAK_SIZE || tweaklen > FF1_MAX_TWEAK_SIZE) { + if (tweaklen < SM4_FF1_MIN_TWEAK_SIZE || tweaklen > SM4_FF1_MAX_TWEAK_SIZE) { error_print(); return -1; } @@ -110,27 +99,24 @@ static int ff1_check_args(const BLOCK_CIPHER_KEY *key, const char *in, size_t in return 1; } -static int ff1_init_pblock(const BLOCK_CIPHER_KEY *key, uint8_t pblock[16], +static int sm4_ff1_init_pblock(const SM4_KEY *key, uint8_t pblock[16], size_t u, size_t n, size_t tweaklen) { - static const uint8_t ff1_radix10_pblock[16] = { + static const uint8_t sm4_ff1_radix10_pblock[16] = { 0x01, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x0a, 0xff, 0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0xff, }; - memcpy(pblock, ff1_radix10_pblock, 16); + memcpy(pblock, sm4_ff1_radix10_pblock, 16); pblock[7] = (uint8_t)u; PUTU32(pblock + 8, (uint32_t)n); PUTU32(pblock + 12, (uint32_t)tweaklen); - if (block_cipher_encrypt(key, pblock, pblock) != 1) { - error_print(); - return -1; - } + sm4_encrypt(key, pblock, pblock); return 1; } -static int ff1_round(const BLOCK_CIPHER_KEY *key, const uint8_t pblock[16], +static int sm4_ff1_round(const SM4_KEY *key, const uint8_t pblock[16], const uint8_t *tweak, size_t tweaklen, size_t bsize, int round, uint32_t num, uint64_t *y) { uint8_t qblock[32] = {0}; @@ -165,25 +151,19 @@ static int ff1_round(const BLOCK_CIPHER_KEY *key, const uint8_t pblock[16], for (i = 0; i < sizeof(block); i++) { block[i] = pblock[i] ^ qblock[i]; } - if (block_cipher_encrypt(key, block, block) != 1) { - error_print(); - return -1; - } + sm4_encrypt(key, block, block); for (offset = 16; offset < qlen; offset += 16) { for (i = 0; i < sizeof(block); i++) { block[i] ^= qblock[offset + i]; } - if (block_cipher_encrypt(key, block, block) != 1) { - error_print(); - return -1; - } + sm4_encrypt(key, block, block); } *y = GETU64(block); return 1; } -int ff1_encrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, +int sm4_ff1_encrypt(const SM4_KEY *key, const char *in, size_t inlen, const uint8_t *tweak, size_t tweaklen, char *out) { size_t u; @@ -199,7 +179,7 @@ int ff1_encrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, size_t bsize; int i; - if (ff1_check_args(key, in, inlen, tweak, tweaklen, out) != 1) { + if (sm4_ff1_check_args(key, in, inlen, tweak, tweaklen, out) != 1) { error_print(); return -1; } @@ -207,25 +187,25 @@ int ff1_encrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, u = inlen / 2; v = inlen - u; - if (ff1_digits_to_num(in, u, &a) != 1 - || ff1_digits_to_num(in + u, v, &b) != 1 - || ff1_init_pblock(key, pblock, u, inlen, tweaklen) != 1) { + if (sm4_ff1_digits_to_num(in, u, &a) != 1 + || sm4_ff1_digits_to_num(in + u, v, &b) != 1 + || sm4_ff1_init_pblock(key, pblock, u, inlen, tweaklen) != 1) { error_print(); return -1; } alen = u; blen = v; - bsize = ff1_radix10_b[v]; + bsize = sm4_ff1_radix10_b[v]; - for (i = 0; i < FF1_NUM_ROUNDS; i++) { + for (i = 0; i < SM4_FF1_NUM_ROUNDS; i++) { size_t m = (i & 1) ? v : u; - if (ff1_round(key, pblock, tweak, tweaklen, bsize, i, b, &y) != 1) { + if (sm4_ff1_round(key, pblock, tweak, tweaklen, bsize, i, b, &y) != 1) { error_print(); return -1; } - ymod = (uint32_t)(y % ff1_radix10_mod[m]); - c = (a + ymod) % ff1_radix10_mod[m]; + ymod = (uint32_t)(y % sm4_ff1_radix10_mod[m]); + c = (a + ymod) % sm4_ff1_radix10_mod[m]; a = b; alen = blen; b = c; @@ -236,15 +216,15 @@ int ff1_encrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, error_print(); return -1; } - if (ff1_num_to_digits(a, alen, out) != 1 - || ff1_num_to_digits(b, blen, out + alen) != 1) { + if (sm4_ff1_num_to_digits(a, alen, out) != 1 + || sm4_ff1_num_to_digits(b, blen, out + alen) != 1) { error_print(); return -1; } return 1; } -int ff1_decrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, +int sm4_ff1_decrypt(const SM4_KEY *key, const char *in, size_t inlen, const uint8_t *tweak, size_t tweaklen, char *out) { size_t u; @@ -260,7 +240,7 @@ int ff1_decrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, size_t bsize; int i; - if (ff1_check_args(key, in, inlen, tweak, tweaklen, out) != 1) { + if (sm4_ff1_check_args(key, in, inlen, tweak, tweaklen, out) != 1) { error_print(); return -1; } @@ -268,30 +248,30 @@ int ff1_decrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, u = inlen / 2; v = inlen - u; - if (ff1_digits_to_num(in, u, &a) != 1 - || ff1_digits_to_num(in + u, v, &b) != 1 - || ff1_init_pblock(key, pblock, u, inlen, tweaklen) != 1) { + if (sm4_ff1_digits_to_num(in, u, &a) != 1 + || sm4_ff1_digits_to_num(in + u, v, &b) != 1 + || sm4_ff1_init_pblock(key, pblock, u, inlen, tweaklen) != 1) { error_print(); return -1; } alen = u; blen = v; - bsize = ff1_radix10_b[v]; + bsize = sm4_ff1_radix10_b[v]; - for (i = FF1_NUM_ROUNDS - 1; i >= 0; i--) { + for (i = SM4_FF1_NUM_ROUNDS - 1; i >= 0; i--) { size_t m = (i & 1) ? v : u; c = b; b = a; blen = alen; - if (ff1_round(key, pblock, tweak, tweaklen, bsize, i, b, &y) != 1) { + if (sm4_ff1_round(key, pblock, tweak, tweaklen, bsize, i, b, &y) != 1) { error_print(); return -1; } - ymod = (uint32_t)(y % ff1_radix10_mod[m]); + ymod = (uint32_t)(y % sm4_ff1_radix10_mod[m]); a = c; - a = (a >= ymod) ? a - ymod : a + ff1_radix10_mod[m] - ymod; + a = (a >= ymod) ? a - ymod : a + sm4_ff1_radix10_mod[m] - ymod; alen = m; } @@ -299,8 +279,8 @@ int ff1_decrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen, error_print(); return -1; } - if (ff1_num_to_digits(a, alen, out) != 1 - || ff1_num_to_digits(b, blen, out + alen) != 1) { + if (sm4_ff1_num_to_digits(a, alen, out) != 1 + || sm4_ff1_num_to_digits(b, blen, out + alen) != 1) { error_print(); return -1; } diff --git a/tests/ff1test.c b/tests/ff1test.c deleted file mode 100644 index 52637bb3..00000000 --- a/tests/ff1test.c +++ /dev/null @@ -1,273 +0,0 @@ -/* - * Copyright 2014-2026 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 - - -typedef struct { - const uint8_t key[16]; - const char *plaintext; - const uint8_t *tweak; - size_t tweaklen; - const char *ciphertext; -} FF1_TEST; - -static const uint8_t ff1_sm4_tweak1[] = { - 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, - 0x31, 0x30, -}; - -static const uint8_t ff1_sm4_tweak2[] = { - 0x37, 0x38, 0x39, 0x36, 0x70, 0x71, 0x72, 0x73, - 0x74, 0x75, 0x76, -}; - -static const FF1_TEST ff1_sm4_tests[] = { - { - { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, - }, - "6226090102675688", - ff1_sm4_tweak1, - sizeof(ff1_sm4_tweak1), - "2326982895499381", - }, - { - { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, - }, - "110107197203192876", - ff1_sm4_tweak2, - sizeof(ff1_sm4_tweak2), - "755842115213533405", - }, - { - { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, - }, - "13687260594", - NULL, - 0, - "37914960556", - }, -}; - -#ifdef ENABLE_AES -static const uint8_t ff1_aes128_tweak1[] = { - 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, - 0x31, 0x30, -}; - -static const uint8_t ff1_aes128_tweak4[] = { - 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, 0x37, -}; - -static const FF1_TEST ff1_aes128_tests[] = { - { - { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, - }, - "0123456789", - ff1_aes128_tweak1, - sizeof(ff1_aes128_tweak1), - "6124200773", - }, - { - { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, - }, - "0123456789", - NULL, - 0, - "2433477484", - }, - { - { - 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, - 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, - }, - "999999999", - ff1_aes128_tweak4, - sizeof(ff1_aes128_tweak4), - "658229573", - }, -}; -#endif - -static int test_ff1_sm4(void) -{ - const char *plaintext = "99999999999999999"; - size_t plaintext_len = strlen(plaintext); - const char sentinel = '#'; - const uint8_t key[16] = {0}; - const uint8_t tweak[8] = { - 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, - }; - BLOCK_CIPHER_KEY block_key; - char ciphertext[FF1_MAX_DIGITS + 1]; - char decrypted[FF1_MAX_DIGITS + 1]; - - if (ff1_init(&block_key, BLOCK_CIPHER_sm4(), key) != 1) { - error_print(); - return -1; - } - ciphertext[plaintext_len] = sentinel; - if (ff1_encrypt(&block_key, plaintext, plaintext_len, - tweak, sizeof(tweak), ciphertext) != 1) { - error_print(); - return -1; - } - if (ciphertext[plaintext_len] != sentinel) { - error_print(); - return -1; - } - ciphertext[plaintext_len] = '\0'; - decrypted[plaintext_len] = sentinel; - if (ff1_decrypt(&block_key, ciphertext, plaintext_len, - tweak, sizeof(tweak), decrypted) != 1) { - error_print(); - return -1; - } - if (decrypted[plaintext_len] != sentinel) { - error_print(); - return -1; - } - decrypted[plaintext_len] = '\0'; - if (strcmp(plaintext, decrypted) != 0) { - error_print(); - return -1; - } - - printf("ff1-sm4-encrypt(\"%s\") = \"%s\"\n", plaintext, ciphertext); - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -static int test_ff1_sm4_vectors(void) -{ - BLOCK_CIPHER_KEY block_key; - char ciphertext[FF1_MAX_DIGITS + 1]; - char decrypted[FF1_MAX_DIGITS + 1]; - size_t i; - int err = 0; - - for (i = 0; i < sizeof(ff1_sm4_tests)/sizeof(ff1_sm4_tests[0]); i++) { - const FF1_TEST *test = &ff1_sm4_tests[i]; - - if (ff1_init(&block_key, BLOCK_CIPHER_sm4(), test->key) != 1) { - error_print(); - return -1; - } - if (ff1_encrypt(&block_key, test->plaintext, strlen(test->plaintext), - test->tweak, test->tweaklen, ciphertext) != 1) { - error_print(); - return -1; - } - ciphertext[strlen(test->plaintext)] = '\0'; - if (strcmp(ciphertext, test->ciphertext) != 0) { - fprintf(stderr, "test %zu: got %s, expected %s\n", - i + 1, ciphertext, test->ciphertext); - error_print(); - err++; - continue; - } - if (ff1_decrypt(&block_key, test->ciphertext, strlen(test->ciphertext), - test->tweak, test->tweaklen, decrypted) != 1) { - error_print(); - return -1; - } - decrypted[strlen(test->ciphertext)] = '\0'; - if (strcmp(decrypted, test->plaintext) != 0) { - error_print(); - return -1; - } - } - if (err) { - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} - -#ifdef ENABLE_AES -static int test_ff1_aes128_vectors(void) -{ - BLOCK_CIPHER_KEY block_key; - char ciphertext[FF1_MAX_DIGITS + 1]; - char decrypted[FF1_MAX_DIGITS + 1]; - size_t i; - int err = 0; - - for (i = 0; i < sizeof(ff1_aes128_tests)/sizeof(ff1_aes128_tests[0]); i++) { - const FF1_TEST *test = &ff1_aes128_tests[i]; - - if (ff1_init(&block_key, BLOCK_CIPHER_aes128(), test->key) != 1) { - error_print(); - return -1; - } - if (ff1_encrypt(&block_key, test->plaintext, strlen(test->plaintext), - test->tweak, test->tweaklen, ciphertext) != 1) { - error_print(); - return -1; - } - ciphertext[strlen(test->plaintext)] = '\0'; - if (strcmp(ciphertext, test->ciphertext) != 0) { - fprintf(stderr, "AES-128 test %zu: got %s, expected %s\n", - i + 1, ciphertext, test->ciphertext); - error_print(); - err++; - continue; - } - if (ff1_decrypt(&block_key, test->ciphertext, strlen(test->ciphertext), - test->tweak, test->tweaklen, decrypted) != 1) { - error_print(); - return -1; - } - decrypted[strlen(test->ciphertext)] = '\0'; - if (strcmp(decrypted, test->plaintext) != 0) { - error_print(); - return -1; - } - } - if (err) { - return -1; - } - - printf("%s() ok\n", __FUNCTION__); - return 1; -} -#endif - -int main(void) -{ - int err = 0; - - if (test_ff1_sm4() != 1) { - err++; - } - if (test_ff1_sm4_vectors() != 1) { - err++; - } -#ifdef ENABLE_AES - if (test_ff1_aes128_vectors() != 1) { - err++; - } -#endif - - return err; -} diff --git a/tests/sm4_ff1test.c b/tests/sm4_ff1test.c new file mode 100644 index 00000000..b825e9fd --- /dev/null +++ b/tests/sm4_ff1test.c @@ -0,0 +1,175 @@ +/* + * Copyright 2014-2026 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 + + +typedef struct { + const uint8_t key[16]; + const char *plaintext; + const uint8_t *tweak; + size_t tweaklen; + const char *ciphertext; +} SM4_FF1_TEST; + +static const uint8_t sm4_ff1_sm4_tweak1[] = { + 0x39, 0x38, 0x37, 0x36, 0x35, 0x34, 0x33, 0x32, + 0x31, 0x30, +}; + +static const uint8_t sm4_ff1_sm4_tweak2[] = { + 0x37, 0x38, 0x39, 0x36, 0x70, 0x71, 0x72, 0x73, + 0x74, 0x75, 0x76, +}; + +static const SM4_FF1_TEST sm4_ff1_sm4_tests[] = { + { + { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + }, + "6226090102675688", + sm4_ff1_sm4_tweak1, + sizeof(sm4_ff1_sm4_tweak1), + "2326982895499381", + }, + { + { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + }, + "110107197203192876", + sm4_ff1_sm4_tweak2, + sizeof(sm4_ff1_sm4_tweak2), + "755842115213533405", + }, + { + { + 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, + 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c, + }, + "13687260594", + NULL, + 0, + "37914960556", + }, +}; + +static int test_sm4_ff1(void) +{ + const char *plaintext = "99999999999999999"; + size_t plaintext_len = strlen(plaintext); + const char sentinel = '#'; + const uint8_t key[16] = {0}; + const uint8_t tweak[8] = { + 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, + }; + SM4_KEY sm4_key; + char ciphertext[SM4_FF1_MAX_DIGITS + 1]; + char decrypted[SM4_FF1_MAX_DIGITS + 1]; + + if (sm4_ff1_init(&sm4_key, key) != 1) { + error_print(); + return -1; + } + ciphertext[plaintext_len] = sentinel; + if (sm4_ff1_encrypt(&sm4_key, plaintext, plaintext_len, + tweak, sizeof(tweak), ciphertext) != 1) { + error_print(); + return -1; + } + if (ciphertext[plaintext_len] != sentinel) { + error_print(); + return -1; + } + ciphertext[plaintext_len] = '\0'; + decrypted[plaintext_len] = sentinel; + if (sm4_ff1_decrypt(&sm4_key, ciphertext, plaintext_len, + tweak, sizeof(tweak), decrypted) != 1) { + error_print(); + return -1; + } + if (decrypted[plaintext_len] != sentinel) { + error_print(); + return -1; + } + decrypted[plaintext_len] = '\0'; + if (strcmp(plaintext, decrypted) != 0) { + error_print(); + return -1; + } + + printf("sm4_ff1_encrypt(\"%s\") = \"%s\"\n", plaintext, ciphertext); + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_ff1_vectors(void) +{ + SM4_KEY sm4_key; + char ciphertext[SM4_FF1_MAX_DIGITS + 1]; + char decrypted[SM4_FF1_MAX_DIGITS + 1]; + size_t i; + int err = 0; + + for (i = 0; i < sizeof(sm4_ff1_sm4_tests)/sizeof(sm4_ff1_sm4_tests[0]); i++) { + const SM4_FF1_TEST *test = &sm4_ff1_sm4_tests[i]; + + if (sm4_ff1_init(&sm4_key, test->key) != 1) { + error_print(); + return -1; + } + if (sm4_ff1_encrypt(&sm4_key, test->plaintext, strlen(test->plaintext), + test->tweak, test->tweaklen, ciphertext) != 1) { + error_print(); + return -1; + } + ciphertext[strlen(test->plaintext)] = '\0'; + if (strcmp(ciphertext, test->ciphertext) != 0) { + fprintf(stderr, "test %zu: got %s, expected %s\n", + i + 1, ciphertext, test->ciphertext); + error_print(); + err++; + continue; + } + if (sm4_ff1_decrypt(&sm4_key, test->ciphertext, strlen(test->ciphertext), + test->tweak, test->tweaklen, decrypted) != 1) { + error_print(); + return -1; + } + decrypted[strlen(test->ciphertext)] = '\0'; + if (strcmp(decrypted, test->plaintext) != 0) { + error_print(); + return -1; + } + } + if (err) { + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +int main(void) +{ + int err = 0; + + if (test_sm4_ff1() != 1) { + err++; + } + if (test_sm4_ff1_vectors() != 1) { + err++; + } + + return err; +} diff --git a/tools/sm4_ff1.c b/tools/sm4_ff1.c index 8481e603..9721c22b 100644 --- a/tools/sm4_ff1.c +++ b/tools/sm4_ff1.c @@ -12,13 +12,12 @@ #include #include #include -#include +#include #include #include #include -#define SM4_FF1_MAX_TWEAK_SIZE FF1_MAX_TWEAK_SIZE #define ID_CARD_DIGITS 18 #define ID_CARD_BODY_DIGITS 17 @@ -152,7 +151,7 @@ static int bankcard_check(const char *s, size_t len) { int ch; - if (!s || len < FF1_MIN_DIGITS + 1 || len > FF1_MAX_DIGITS + 1 || !is_digits(s, len)) { + if (!s || len < SM4_FF1_MIN_DIGITS + 1 || len > SM4_FF1_MAX_DIGITS + 1 || !is_digits(s, len)) { return -1; } ch = luhn_check_digit(s, len - 1); @@ -179,9 +178,9 @@ int sm4_ff1_main(int argc, char **argv) uint8_t *inbuf = NULL; int inbuf_alloc = 0; size_t inlen; - char outbuf[FF1_MAX_DIGITS + 2]; + char outbuf[SM4_FF1_MAX_DIGITS + 2]; size_t bodylen; - BLOCK_CIPHER_KEY block_key; + SM4_KEY sm4_key; argc--; argv++; @@ -272,7 +271,7 @@ bad: fprintf(stderr, "gmssl %s: option `-key` missing\n", prog); goto end; } - if (tweakhex && tweaklen > FF1_MAX_TWEAK_SIZE) { + if (tweakhex && tweaklen > SM4_FF1_MAX_TWEAK_SIZE) { fprintf(stderr, "gmssl %s: invalid tweak length\n", prog); goto end; } @@ -303,24 +302,24 @@ bad: } bodylen = inlen - 1; } else { - if (inlen < FF1_MIN_DIGITS || inlen > FF1_MAX_DIGITS || !is_digits((char *)inbuf, inlen)) { + if (inlen < SM4_FF1_MIN_DIGITS || inlen > SM4_FF1_MAX_DIGITS || !is_digits((char *)inbuf, inlen)) { fprintf(stderr, "gmssl %s: invalid input digits\n", prog); goto end; } bodylen = inlen; } - if (ff1_init(&block_key, BLOCK_CIPHER_sm4(), key) != 1) { + if (sm4_ff1_init(&sm4_key, key) != 1) { error_print(); goto end; } if (enc) { - if (ff1_encrypt(&block_key, (char *)inbuf, bodylen, tweak, tweaklen, outbuf) != 1) { + if (sm4_ff1_encrypt(&sm4_key, (char *)inbuf, bodylen, tweak, tweaklen, outbuf) != 1) { error_print(); goto end; } } else { - if (ff1_decrypt(&block_key, (char *)inbuf, bodylen, tweak, tweaklen, outbuf) != 1) { + if (sm4_ff1_decrypt(&sm4_key, (char *)inbuf, bodylen, tweak, tweaklen, outbuf) != 1) { error_print(); goto end; } @@ -361,6 +360,6 @@ end: if (inbuf_alloc) free(inbuf); gmssl_secure_clear(key, sizeof(key)); gmssl_secure_clear(tweak, sizeof(tweak)); - gmssl_secure_clear(&block_key, sizeof(block_key)); + gmssl_secure_clear(&sm4_key, sizeof(sm4_key)); return ret; }