mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-08-06 11:53:39 +08:00
Update sm4_ff1
This commit is contained in:
@@ -487,9 +487,9 @@ endif()
|
|||||||
if (ENABLE_SM4_FF1)
|
if (ENABLE_SM4_FF1)
|
||||||
message(STATUS "ENABLE_SM4_FF1 is ON")
|
message(STATUS "ENABLE_SM4_FF1 is ON")
|
||||||
add_definitions(-DENABLE_SM4_FF1)
|
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 tools tools/sm4_ff1.c)
|
||||||
list(APPEND tests ff1)
|
list(APPEND tests sm4_ff1)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
@@ -1025,7 +1025,7 @@ endif()
|
|||||||
#
|
#
|
||||||
set(CPACK_PACKAGE_NAME "GmSSL")
|
set(CPACK_PACKAGE_NAME "GmSSL")
|
||||||
set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
|
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_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
|
||||||
set(CPACK_NSIS_MODIFY_PATH ON)
|
set(CPACK_NSIS_MODIFY_PATH ON)
|
||||||
include(CPack)
|
include(CPack)
|
||||||
|
|||||||
@@ -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)
|
-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)
|
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 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_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_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_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)
|
if(ENABLE_SM4_ECB)
|
||||||
gmssl_symmetric_roundtrip(tool_sm4_ecb sm4_ecb -key ${SM4_KEY})
|
gmssl_symmetric_roundtrip(tool_sm4_ecb sm4_ecb -key ${SM4_KEY})
|
||||||
gmssl_symmetric_roundtrip(tool_sm4_unified_ecb sm4 -ecb -key ${SM4_KEY})
|
|
||||||
endif()
|
endif()
|
||||||
if(ENABLE_SM4_CFB)
|
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_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()
|
endif()
|
||||||
if(ENABLE_SM4_OFB)
|
if(ENABLE_SM4_OFB)
|
||||||
gmssl_symmetric_roundtrip(tool_sm4_ofb sm4_ofb -key ${SM4_KEY} -iv ${SM4_IV})
|
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()
|
endif()
|
||||||
if(ENABLE_SM4_CCM)
|
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_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()
|
endif()
|
||||||
if(ENABLE_SM4_XTS)
|
if(ENABLE_SM4_XTS)
|
||||||
file(WRITE tool_sm4_xts.plain "0123456789abcdef0123456789abcdef")
|
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
|
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)
|
-in tool_sm4_xts.cipher -out tool_sm4_xts.decrypt)
|
||||||
gmssl_files_equal(tool_sm4_xts.plain 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()
|
endif()
|
||||||
if(ENABLE_SM4_FF1)
|
if(ENABLE_SM4_FF1)
|
||||||
gmssl_expect_stdout("2326982895499381\n"
|
gmssl_expect_stdout("2326982895499381\n"
|
||||||
|
|||||||
@@ -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 <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include <gmssl/block_cipher.h>
|
|
||||||
|
|
||||||
|
|
||||||
#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
|
|
||||||
@@ -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
|
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||||
* not use this file except in compliance with the License.
|
* 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
|
#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
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ extern "C" {
|
|||||||
|
|
||||||
|
|
||||||
#define GMSSL_VERSION_NUM 30300
|
#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);
|
int gmssl_version_num(void);
|
||||||
const char *gmssl_version_str(void);
|
const char *gmssl_version_str(void);
|
||||||
|
|||||||
@@ -7,13 +7,13 @@
|
|||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <gmssl/ff1.h>
|
#include <gmssl/sm4.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <gmssl/endian.h>
|
#include <gmssl/endian.h>
|
||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
|
|
||||||
|
|
||||||
static const uint32_t ff1_radix10_mod[] = {
|
static const uint32_t sm4_ff1_radix10_mod[] = {
|
||||||
1,
|
1,
|
||||||
10,
|
10,
|
||||||
100,
|
100,
|
||||||
@@ -26,33 +26,26 @@ static const uint32_t ff1_radix10_mod[] = {
|
|||||||
1000000000,
|
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,
|
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) {
|
if (!key || !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) {
|
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
sm4_set_encrypt_key(key, raw_key);
|
||||||
return 1;
|
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;
|
uint32_t value = 0;
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (!digits || !num || ndigits > FF1_MAX_DIGITS/2) {
|
if (!digits || !num || ndigits > SM4_FF1_MAX_DIGITS/2) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -67,9 +60,9 @@ static int ff1_digits_to_num(const char *digits, size_t ndigits, uint32_t *num)
|
|||||||
return 1;
|
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();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -80,24 +73,20 @@ static int ff1_num_to_digits(uint32_t num, size_t ndigits, char *digits)
|
|||||||
return 1;
|
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)
|
const uint8_t *tweak, size_t tweaklen, char *out)
|
||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
|
|
||||||
if (!key || !key->cipher || !in || !out || (!tweak && tweaklen)) {
|
if (!key || !in || !out || (!tweak && tweaklen)) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (key->cipher->block_size != BLOCK_CIPHER_BLOCK_SIZE) {
|
if (inlen < SM4_FF1_MIN_DIGITS || inlen > SM4_FF1_MAX_DIGITS) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (inlen < FF1_MIN_DIGITS || inlen > FF1_MAX_DIGITS) {
|
if (tweaklen < SM4_FF1_MIN_TWEAK_SIZE || tweaklen > SM4_FF1_MAX_TWEAK_SIZE) {
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (tweaklen < FF1_MIN_TWEAK_SIZE || tweaklen > FF1_MAX_TWEAK_SIZE) {
|
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -110,27 +99,24 @@ static int ff1_check_args(const BLOCK_CIPHER_KEY *key, const char *in, size_t in
|
|||||||
return 1;
|
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)
|
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,
|
0x01, 0x02, 0x01, 0x00, 0x00, 0x0a, 0x0a, 0xff,
|
||||||
0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 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;
|
pblock[7] = (uint8_t)u;
|
||||||
PUTU32(pblock + 8, (uint32_t)n);
|
PUTU32(pblock + 8, (uint32_t)n);
|
||||||
PUTU32(pblock + 12, (uint32_t)tweaklen);
|
PUTU32(pblock + 12, (uint32_t)tweaklen);
|
||||||
|
|
||||||
if (block_cipher_encrypt(key, pblock, pblock) != 1) {
|
sm4_encrypt(key, pblock, pblock);
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
return 1;
|
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)
|
const uint8_t *tweak, size_t tweaklen, size_t bsize, int round, uint32_t num, uint64_t *y)
|
||||||
{
|
{
|
||||||
uint8_t qblock[32] = {0};
|
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++) {
|
for (i = 0; i < sizeof(block); i++) {
|
||||||
block[i] = pblock[i] ^ qblock[i];
|
block[i] = pblock[i] ^ qblock[i];
|
||||||
}
|
}
|
||||||
if (block_cipher_encrypt(key, block, block) != 1) {
|
sm4_encrypt(key, block, block);
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
for (offset = 16; offset < qlen; offset += 16) {
|
for (offset = 16; offset < qlen; offset += 16) {
|
||||||
for (i = 0; i < sizeof(block); i++) {
|
for (i = 0; i < sizeof(block); i++) {
|
||||||
block[i] ^= qblock[offset + i];
|
block[i] ^= qblock[offset + i];
|
||||||
}
|
}
|
||||||
if (block_cipher_encrypt(key, block, block) != 1) {
|
sm4_encrypt(key, block, block);
|
||||||
error_print();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*y = GETU64(block);
|
*y = GETU64(block);
|
||||||
return 1;
|
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)
|
const uint8_t *tweak, size_t tweaklen, char *out)
|
||||||
{
|
{
|
||||||
size_t u;
|
size_t u;
|
||||||
@@ -199,7 +179,7 @@ int ff1_encrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen,
|
|||||||
size_t bsize;
|
size_t bsize;
|
||||||
int i;
|
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();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -207,25 +187,25 @@ int ff1_encrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen,
|
|||||||
u = inlen / 2;
|
u = inlen / 2;
|
||||||
v = inlen - u;
|
v = inlen - u;
|
||||||
|
|
||||||
if (ff1_digits_to_num(in, u, &a) != 1
|
if (sm4_ff1_digits_to_num(in, u, &a) != 1
|
||||||
|| ff1_digits_to_num(in + u, v, &b) != 1
|
|| sm4_ff1_digits_to_num(in + u, v, &b) != 1
|
||||||
|| ff1_init_pblock(key, pblock, u, inlen, tweaklen) != 1) {
|
|| sm4_ff1_init_pblock(key, pblock, u, inlen, tweaklen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
alen = u;
|
alen = u;
|
||||||
blen = v;
|
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;
|
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();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ymod = (uint32_t)(y % ff1_radix10_mod[m]);
|
ymod = (uint32_t)(y % sm4_ff1_radix10_mod[m]);
|
||||||
c = (a + ymod) % ff1_radix10_mod[m];
|
c = (a + ymod) % sm4_ff1_radix10_mod[m];
|
||||||
a = b;
|
a = b;
|
||||||
alen = blen;
|
alen = blen;
|
||||||
b = c;
|
b = c;
|
||||||
@@ -236,15 +216,15 @@ int ff1_encrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen,
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ff1_num_to_digits(a, alen, out) != 1
|
if (sm4_ff1_num_to_digits(a, alen, out) != 1
|
||||||
|| ff1_num_to_digits(b, blen, out + alen) != 1) {
|
|| sm4_ff1_num_to_digits(b, blen, out + alen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
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)
|
const uint8_t *tweak, size_t tweaklen, char *out)
|
||||||
{
|
{
|
||||||
size_t u;
|
size_t u;
|
||||||
@@ -260,7 +240,7 @@ int ff1_decrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen,
|
|||||||
size_t bsize;
|
size_t bsize;
|
||||||
int i;
|
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();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -268,30 +248,30 @@ int ff1_decrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen,
|
|||||||
u = inlen / 2;
|
u = inlen / 2;
|
||||||
v = inlen - u;
|
v = inlen - u;
|
||||||
|
|
||||||
if (ff1_digits_to_num(in, u, &a) != 1
|
if (sm4_ff1_digits_to_num(in, u, &a) != 1
|
||||||
|| ff1_digits_to_num(in + u, v, &b) != 1
|
|| sm4_ff1_digits_to_num(in + u, v, &b) != 1
|
||||||
|| ff1_init_pblock(key, pblock, u, inlen, tweaklen) != 1) {
|
|| sm4_ff1_init_pblock(key, pblock, u, inlen, tweaklen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
alen = u;
|
alen = u;
|
||||||
blen = v;
|
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;
|
size_t m = (i & 1) ? v : u;
|
||||||
|
|
||||||
c = b;
|
c = b;
|
||||||
b = a;
|
b = a;
|
||||||
blen = alen;
|
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();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
ymod = (uint32_t)(y % ff1_radix10_mod[m]);
|
ymod = (uint32_t)(y % sm4_ff1_radix10_mod[m]);
|
||||||
a = c;
|
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;
|
alen = m;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -299,8 +279,8 @@ int ff1_decrypt(const BLOCK_CIPHER_KEY *key, const char *in, size_t inlen,
|
|||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
if (ff1_num_to_digits(a, alen, out) != 1
|
if (sm4_ff1_num_to_digits(a, alen, out) != 1
|
||||||
|| ff1_num_to_digits(b, blen, out + alen) != 1) {
|
|| sm4_ff1_num_to_digits(b, blen, out + alen) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
273
tests/ff1test.c
273
tests/ff1test.c
@@ -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 <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <gmssl/ff1.h>
|
|
||||||
#include <gmssl/error.h>
|
|
||||||
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
175
tests/sm4_ff1test.c
Normal file
175
tests/sm4_ff1test.c
Normal file
@@ -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 <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <gmssl/sm4.h>
|
||||||
|
#include <gmssl/error.h>
|
||||||
|
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
@@ -12,13 +12,12 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <gmssl/ff1.h>
|
#include <gmssl/sm4.h>
|
||||||
#include <gmssl/hex.h>
|
#include <gmssl/hex.h>
|
||||||
#include <gmssl/mem.h>
|
#include <gmssl/mem.h>
|
||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
|
|
||||||
|
|
||||||
#define SM4_FF1_MAX_TWEAK_SIZE FF1_MAX_TWEAK_SIZE
|
|
||||||
#define ID_CARD_DIGITS 18
|
#define ID_CARD_DIGITS 18
|
||||||
#define ID_CARD_BODY_DIGITS 17
|
#define ID_CARD_BODY_DIGITS 17
|
||||||
|
|
||||||
@@ -152,7 +151,7 @@ static int bankcard_check(const char *s, size_t len)
|
|||||||
{
|
{
|
||||||
int ch;
|
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;
|
return -1;
|
||||||
}
|
}
|
||||||
ch = luhn_check_digit(s, len - 1);
|
ch = luhn_check_digit(s, len - 1);
|
||||||
@@ -179,9 +178,9 @@ int sm4_ff1_main(int argc, char **argv)
|
|||||||
uint8_t *inbuf = NULL;
|
uint8_t *inbuf = NULL;
|
||||||
int inbuf_alloc = 0;
|
int inbuf_alloc = 0;
|
||||||
size_t inlen;
|
size_t inlen;
|
||||||
char outbuf[FF1_MAX_DIGITS + 2];
|
char outbuf[SM4_FF1_MAX_DIGITS + 2];
|
||||||
size_t bodylen;
|
size_t bodylen;
|
||||||
BLOCK_CIPHER_KEY block_key;
|
SM4_KEY sm4_key;
|
||||||
|
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
@@ -272,7 +271,7 @@ bad:
|
|||||||
fprintf(stderr, "gmssl %s: option `-key` missing\n", prog);
|
fprintf(stderr, "gmssl %s: option `-key` missing\n", prog);
|
||||||
goto end;
|
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);
|
fprintf(stderr, "gmssl %s: invalid tweak length\n", prog);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -303,24 +302,24 @@ bad:
|
|||||||
}
|
}
|
||||||
bodylen = inlen - 1;
|
bodylen = inlen - 1;
|
||||||
} else {
|
} 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);
|
fprintf(stderr, "gmssl %s: invalid input digits\n", prog);
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
bodylen = inlen;
|
bodylen = inlen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ff1_init(&block_key, BLOCK_CIPHER_sm4(), key) != 1) {
|
if (sm4_ff1_init(&sm4_key, key) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
if (enc) {
|
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();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
} else {
|
} 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();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
@@ -361,6 +360,6 @@ end:
|
|||||||
if (inbuf_alloc) free(inbuf);
|
if (inbuf_alloc) free(inbuf);
|
||||||
gmssl_secure_clear(key, sizeof(key));
|
gmssl_secure_clear(key, sizeof(key));
|
||||||
gmssl_secure_clear(tweak, sizeof(tweak));
|
gmssl_secure_clear(tweak, sizeof(tweak));
|
||||||
gmssl_secure_clear(&block_key, sizeof(block_key));
|
gmssl_secure_clear(&sm4_key, sizeof(sm4_key));
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user