Fix SM4 API bugs and change behavior

This commit is contained in:
Zhi Guan
2026-06-13 22:14:56 +08:00
parent 8fded4abc7
commit c12edeb7b1
29 changed files with 1281 additions and 212 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 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.
@@ -39,18 +39,27 @@ static int test_sm4_cbc_mac(void)
sm4_cbc_encrypt_blocks(&sm4_key, iv, m, sizeof(m)/16, c);
memcpy(mac1, c + sizeof(m) - 16, 16);
sm4_cbc_mac_init(&ctx, key);
if (sm4_cbc_mac_init(&ctx, key) != 1) {
error_print();
return -1;
}
p = m;
len = 0;
left = sizeof(m);
while (left) {
len = left < len ? left : len;
sm4_cbc_mac_update(&ctx, p, len);
if (sm4_cbc_mac_update(&ctx, p, len) != 1) {
error_print();
return -1;
}
p += len;
left -= len;
len++;
}
sm4_cbc_mac_finish(&ctx, mac2);
if (sm4_cbc_mac_finish(&ctx, mac2) != 1) {
error_print();
return -1;
}
if (memcmp(mac1, mac2, 16)) {
error_print();
return -1;
@@ -62,18 +71,27 @@ static int test_sm4_cbc_mac(void)
sm4_cbc_encrypt_blocks(&sm4_key, iv, m, sizeof(m)/16, c);
memcpy(mac1, c + sizeof(m) - 16, 16);
sm4_cbc_mac_init(&ctx, key);
if (sm4_cbc_mac_init(&ctx, key) != 1) {
error_print();
return -1;
}
p = m;
len = 0;
left = sizeof(m) - 1;
while (left) {
len = left < len ? left : len;
sm4_cbc_mac_update(&ctx, p, len);
if (sm4_cbc_mac_update(&ctx, p, len) != 1) {
error_print();
return -1;
}
p += len;
left -= len;
len++;
}
sm4_cbc_mac_finish(&ctx, mac2);
if (sm4_cbc_mac_finish(&ctx, mac2) != 1) {
error_print();
return -1;
}
if (memcmp(mac1, mac2, 16)) {
error_print();
return -1;
@@ -83,8 +101,64 @@ static int test_sm4_cbc_mac(void)
return 1;
}
static int test_sm4_cbc_mac_args(void)
{
SM4_CBC_MAC_CTX ctx;
uint8_t key[16] = {0};
uint8_t data[16] = {0};
uint8_t mac[16];
if (sm4_cbc_mac_init(NULL, key) != -1
|| sm4_cbc_mac_init(&ctx, NULL) != -1) {
error_print();
return -1;
}
if (sm4_cbc_mac_init(&ctx, key) != 1
|| sm4_cbc_mac_update(NULL, data, sizeof(data)) != -1
|| sm4_cbc_mac_update(&ctx, NULL, sizeof(data)) != -1
|| sm4_cbc_mac_update(&ctx, NULL, 0) != 1
|| sm4_cbc_mac_finish(NULL, mac) != -1
|| sm4_cbc_mac_finish(&ctx, NULL) != -1) {
error_print();
return -1;
}
ctx.ivlen = 16;
if (sm4_cbc_mac_update(&ctx, data, sizeof(data)) != -1
|| sm4_cbc_mac_finish(&ctx, mac) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_cbc_mac_finish_repeat(void)
{
SM4_CBC_MAC_CTX ctx;
uint8_t key[16] = {0};
uint8_t data[15] = {0};
uint8_t mac1[16];
uint8_t mac2[16];
if (sm4_cbc_mac_init(&ctx, key) != 1
|| sm4_cbc_mac_update(&ctx, data, sizeof(data)) != 1
|| sm4_cbc_mac_finish(&ctx, mac1) != 1
|| sm4_cbc_mac_finish(&ctx, mac2) != 1
|| memcmp(mac1, mac2, sizeof(mac1)) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
if (test_sm4_cbc_mac() != 1) { error_print(); return -1; }
if (test_sm4_cbc_mac_args() != 1) { error_print(); return -1; }
if (test_sm4_cbc_mac_finish_repeat() != 1) { error_print(); return -1; }
return 0;
}

View File

@@ -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.
@@ -209,6 +209,98 @@ static int test_sm4_cbc_padding(void)
return 1;
}
static int test_sm4_cbc_args(void)
{
SM4_KEY enc_key;
SM4_KEY dec_key;
SM4_CBC_CTX ctx;
uint8_t key[16] = {0};
uint8_t iv[16] = {0};
uint8_t in[16] = {0};
uint8_t out[32];
size_t outlen;
sm4_set_encrypt_key(&enc_key, key);
sm4_set_decrypt_key(&dec_key, key);
if (sm4_cbc_padding_encrypt(NULL, iv, in, sizeof(in), out, &outlen) != -1
|| sm4_cbc_padding_encrypt(&enc_key, NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cbc_padding_encrypt(&enc_key, iv, NULL, 1, out, &outlen) != -1
|| sm4_cbc_padding_encrypt(&enc_key, iv, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cbc_padding_encrypt(&enc_key, iv, in, sizeof(in), out, NULL) != -1) {
error_print();
return -1;
}
outlen = 0;
if (sm4_cbc_padding_encrypt(&enc_key, iv, NULL, 0, out, &outlen) != 1
|| outlen != SM4_BLOCK_SIZE) {
error_print();
return -1;
}
if (sm4_cbc_padding_encrypt(&enc_key, iv, in, sizeof(in), out, &outlen) != 1
|| outlen != 2 * SM4_BLOCK_SIZE) {
error_print();
return -1;
}
out[outlen - 1] ^= 1;
memset(in, 0xa5, sizeof(in));
if (sm4_cbc_padding_decrypt(&dec_key, iv, out, outlen, in, &outlen) == 1) {
error_print();
return -1;
}
for (outlen = 0; outlen < sizeof(in); outlen++) {
if (in[outlen] != 0xa5) {
error_print();
return -1;
}
}
outlen = 0;
if (sm4_cbc_padding_encrypt(&enc_key, iv, NULL, 0, out, &outlen) != 1
|| outlen != SM4_BLOCK_SIZE) {
error_print();
return -1;
}
if (sm4_cbc_padding_decrypt(NULL, iv, out, outlen, in, &outlen) != -1
|| sm4_cbc_padding_decrypt(&dec_key, NULL, out, outlen, in, &outlen) != -1
|| sm4_cbc_padding_decrypt(&dec_key, iv, NULL, 1, in, &outlen) != -1
|| sm4_cbc_padding_decrypt(&dec_key, iv, out, outlen, NULL, &outlen) != -1
|| sm4_cbc_padding_decrypt(&dec_key, iv, out, outlen, in, NULL) != -1) {
error_print();
return -1;
}
outlen = 123;
if (sm4_cbc_padding_decrypt(&dec_key, iv, NULL, 0, in, &outlen) != -1) {
error_print();
return -1;
}
if (sm4_cbc_encrypt_init(&ctx, key, iv) != 1
|| sm4_cbc_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cbc_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cbc_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1) {
error_print();
return -1;
}
if (sm4_cbc_decrypt_init(&ctx, key, iv) != 1
|| sm4_cbc_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cbc_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cbc_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_cbc_padding_openssl(void)
{
size_t i;
@@ -342,6 +434,20 @@ static int test_sm4_cbc_ctx(void)
return -1;
}
// check in-place decrypt
memcpy(pbuf, cbuf, clen);
if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1
|| sm4_cbc_decrypt_update(&dec_ctx, pbuf, 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
@@ -423,6 +529,7 @@ 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_args() != 1) goto err;
if (test_sm4_cbc_padding_openssl() != 1) goto err;
if (test_sm4_cbc_ctx() != 1) goto err;
printf("%s all tests passed\n", __FILE__);

View File

@@ -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.
@@ -79,13 +79,22 @@ static int test_sm4_ccm_test_vectors(void)
char *ciphertext;
} tests[] = {
{
"rfc8998",
"0123456789abcdeffedcba9876543210",
"00001234567800000000abcd",
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
"16842d4fa186f56ab33256971fa110f4",
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa",
"48af93501fa62adbcd414cce6034d895dda1bf8f132f042098661572e7483094fd12e518ce062c98acee28d95df4416bed31a2f04476c18bb40c84a74b97dc5b",
"rfc8998",
"0123456789abcdeffedcba9876543210",
"00001234567800000000abcd",
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
"16842d4fa186f56ab33256971fa110f4",
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa",
"48af93501fa62adbcd414cce6034d895dda1bf8f132f042098661572e7483094fd12e518ce062c98acee28d95df4416bed31a2f04476c18bb40c84a74b97dc5b",
},
{
"openssl-sm4-ccm-aad-padding-boundary",
"0123456789abcdeffedcba9876543210",
"000102030405060708090a0b",
"101112131415161718191a1b1c1d",
"7290e28b5fa29391036f06a0",
"202122232425262728292a2b2c2d2e",
"374bfae945b38c4082d62a0b4304a0",
},
};
@@ -177,6 +186,66 @@ static int test_sm4_ccm_test_vectors(void)
}
static int test_sm4_ccm_aad_padding_bug(void)
{
const char *hex_key = "0123456789abcdeffedcba9876543210";
const char *hex_iv = "000102030405060708090a0b";
const char *hex_aad = "101112131415161718191a1b1c1d";
const char *hex_msg = "202122232425262728292a2b2c2d2e";
const char *hex_ct = "374bfae945b38c4082d62a0b4304a0";
const char *hex_tag = "7290e28b5fa29391036f06a0";
SM4_KEY sm4_key;
uint8_t key[16];
uint8_t iv[16];
uint8_t aad[16];
uint8_t msg[16];
uint8_t ct[16];
uint8_t tag[16];
uint8_t out[16];
uint8_t dec[16];
uint8_t mac[16];
size_t keylen, ivlen, aadlen, msglen, ctlen, taglen;
if (hex_to_bytes(hex_key, strlen(hex_key), key, &keylen) != 1
|| hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen) != 1
|| hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen) != 1
|| hex_to_bytes(hex_msg, strlen(hex_msg), msg, &msglen) != 1
|| hex_to_bytes(hex_ct, strlen(hex_ct), ct, &ctlen) != 1
|| hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen) != 1) {
error_print();
return -1;
}
/*
* Regression for `alen + aadlen % 16`.
* Short AAD uses alen = 2. Here aadlen = 14, so
* `(alen + aadlen) % 16` is 0 and no zero padding block is added.
*/
if (aadlen != 14 || (2 + aadlen) % 16 != 0) {
error_print();
return -1;
}
sm4_set_encrypt_key(&sm4_key, key);
if (sm4_ccm_encrypt(&sm4_key, iv, ivlen, aad, aadlen,
msg, msglen, out, taglen, mac) != 1
|| ctlen != msglen
|| memcmp(out, ct, ctlen) != 0
|| memcmp(mac, tag, taglen) != 0) {
error_print();
return -1;
}
if (sm4_ccm_decrypt(&sm4_key, iv, ivlen, aad, aadlen,
ct, ctlen, tag, taglen, dec) != 1
|| memcmp(dec, msg, msglen) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_ccm_wycheproof(void)
{
size_t i;
@@ -242,6 +311,59 @@ static int test_sm4_ccm_wycheproof(void)
return 1;
}
static int test_sm4_ccm_args(void)
{
SM4_KEY sm4_key;
uint8_t key[16] = {0};
uint8_t iv[12] = {0};
uint8_t aad[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
uint8_t dec[16];
uint8_t tag[16];
sm4_set_encrypt_key(&sm4_key, key);
if (sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), NULL, 0, NULL, 0, out, 16, tag) != 1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), NULL, 0, NULL, 0, tag, 16, dec) != 1) {
error_print();
return -1;
}
if (sm4_ccm_encrypt(NULL, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, NULL, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, 6, aad, sizeof(aad), in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, 14, aad, sizeof(aad), in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), NULL, 1, in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), NULL, 1, out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), NULL, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 16, NULL) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 3, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 17, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 5, tag) != -1) {
error_print();
return -1;
}
if (sm4_ccm_decrypt(NULL, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, NULL, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, 6, aad, sizeof(aad), in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, 14, aad, sizeof(aad), in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), NULL, 1, in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), NULL, 1, tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), NULL, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 16, NULL) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 3, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 17, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 5, out) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int speed_sm4_ccm_encrypt(void)
{
SM4_KEY sm4_key;
@@ -275,7 +397,9 @@ int main(void)
{
if (test_sm4_ccm() != 1) goto err;
if (test_sm4_ccm_test_vectors() != 1) goto err;
if (test_sm4_ccm_aad_padding_bug() != 1) goto err;
if (test_sm4_ccm_wycheproof() != 1) goto err;
if (test_sm4_ccm_args() != 1) goto err;
#if ENABLE_TEST_SPEED
if (speed_sm4_ccm_encrypt() != 1) goto err;
#endif

View File

@@ -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.
@@ -260,11 +260,69 @@ static int test_sm4_cfb_ctx(void)
return 1;
}
static int test_sm4_cfb_args(void)
{
SM4_CFB_CTX ctx;
uint8_t key[16] = {0};
uint8_t iv[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
size_t outlen;
if (sm4_cfb_encrypt_init(NULL, SM4_CFB_128, key, iv) != -1
|| sm4_cfb_encrypt_init(&ctx, 0, key, iv) != -1
|| sm4_cfb_encrypt_init(&ctx, SM4_BLOCK_SIZE + 1, key, iv) != -1
|| sm4_cfb_encrypt_init(&ctx, SM4_CFB_128, NULL, iv) != -1
|| sm4_cfb_encrypt_init(&ctx, SM4_CFB_128, key, NULL) != -1
|| sm4_cfb_decrypt_init(NULL, SM4_CFB_128, key, iv) != -1
|| sm4_cfb_decrypt_init(&ctx, 0, key, iv) != -1
|| sm4_cfb_decrypt_init(&ctx, SM4_BLOCK_SIZE + 1, key, iv) != -1
|| sm4_cfb_decrypt_init(&ctx, SM4_CFB_128, NULL, iv) != -1
|| sm4_cfb_decrypt_init(&ctx, SM4_CFB_128, key, NULL) != -1) {
error_print();
return -1;
}
if (sm4_cfb_encrypt_init(&ctx, SM4_CFB_128, key, iv) != 1
|| sm4_cfb_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cfb_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_cfb_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cfb_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_cfb_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cfb_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cfb_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_cfb_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_cfb_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_cfb_decrypt_init(&ctx, SM4_CFB_128, key, iv) != 1
|| sm4_cfb_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cfb_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_cfb_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cfb_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_cfb_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cfb_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cfb_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_cfb_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_cfb_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
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;
if (test_sm4_cfb_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:

View File

@@ -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.
@@ -425,6 +425,96 @@ static int test_sm4_ctr_ctx_multi_updates(void)
return 1;
}
static int test_sm4_ctr_args(void)
{
SM4_CTR_CTX ctx;
uint8_t key[16] = {0};
uint8_t ctr[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
size_t outlen;
if (sm4_ctr_encrypt_init(NULL, key, ctr) != -1
|| sm4_ctr_encrypt_init(&ctx, NULL, ctr) != -1
|| sm4_ctr_encrypt_init(&ctx, key, NULL) != -1
|| sm4_ctr32_encrypt_init(NULL, key, ctr) != -1
|| sm4_ctr32_encrypt_init(&ctx, NULL, ctr) != -1
|| sm4_ctr32_encrypt_init(&ctx, key, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ctr_encrypt_init(&ctx, key, ctr) != 1
|| sm4_ctr_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ctr_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ctr_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ctr_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ctr_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ctr_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ctr_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ctr_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ctr_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ctr32_encrypt_init(&ctx, key, ctr) != 1
|| sm4_ctr32_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ctr32_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ctr32_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ctr32_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ctr32_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ctr32_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ctr32_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ctr32_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ctr32_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_ctr_finish_no_extra_counter(void)
{
SM4_CTR_CTX ctx;
uint8_t key[16] = {0};
uint8_t ctr[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
uint8_t expected_ctr[16];
size_t outlen;
memcpy(expected_ctr, ctr, sizeof(expected_ctr));
expected_ctr[15]++;
if (sm4_ctr_encrypt_init(&ctx, key, ctr) != 1
|| sm4_ctr_encrypt_update(&ctx, in, sizeof(in), out, &outlen) != 1
|| outlen != sizeof(in)
|| sm4_ctr_encrypt_finish(&ctx, out, &outlen) != 1
|| outlen != 0
|| memcmp(ctx.ctr, expected_ctr, sizeof(expected_ctr)) != 0) {
error_print();
return -1;
}
if (sm4_ctr32_encrypt_init(&ctx, key, ctr) != 1
|| sm4_ctr32_encrypt_update(&ctx, in, sizeof(in), out, &outlen) != 1
|| outlen != sizeof(in)
|| sm4_ctr32_encrypt_finish(&ctx, out, &outlen) != 1
|| outlen != 0
|| memcmp(ctx.ctr, expected_ctr, sizeof(expected_ctr)) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
if (test_sm4_ctr() != 1) goto err;
@@ -433,6 +523,8 @@ int main(void)
if (test_sm4_ctr_iv_overflow() != 1) goto err;
if (test_sm4_ctr_ctx() != 1) goto err;
if (test_sm4_ctr_ctx_multi_updates() != 1) goto err;
if (test_sm4_ctr_args() != 1) goto err;
if (test_sm4_ctr_finish_no_extra_counter() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:

View File

@@ -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.
@@ -180,11 +180,62 @@ static int test_sm4_ecb_ctx(void)
return 1;
}
static int test_sm4_ecb_args(void)
{
SM4_ECB_CTX ctx;
uint8_t key[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
size_t outlen;
if (sm4_ecb_encrypt_init(NULL, key) != -1
|| sm4_ecb_encrypt_init(&ctx, NULL) != -1
|| sm4_ecb_decrypt_init(NULL, key) != -1
|| sm4_ecb_decrypt_init(&ctx, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ecb_encrypt_init(&ctx, key) != 1
|| sm4_ecb_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ecb_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ecb_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ecb_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ecb_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ecb_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ecb_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ecb_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ecb_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ecb_decrypt_init(&ctx, key) != 1
|| sm4_ecb_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ecb_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ecb_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ecb_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ecb_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ecb_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ecb_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_ecb_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ecb_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
if (test_sm4_ecb() != 1) goto err;
if (test_sm4_ecb_test_vectors() != 1) goto err;
if (test_sm4_ecb_ctx() != 1) goto err;
if (test_sm4_ecb_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2014-2022 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.
@@ -314,6 +314,146 @@ static int test_sm4_gcm_ctx(void)
return 1;
}
static int test_sm4_gcm_args(void)
{
SM4_KEY sm4_key;
SM4_GCM_CTX ctx;
uint8_t key[16] = {0};
uint8_t iv[12] = {0};
uint8_t aad[16] = {0};
uint8_t in[16] = {0};
uint8_t out[64];
uint8_t tag[16];
size_t outlen;
sm4_set_encrypt_key(&sm4_key, key);
if (sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), NULL, 0, NULL, 0, out, sizeof(tag), tag) != 1
|| sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), NULL, 0, NULL, 0, tag, sizeof(tag), out) != 1) {
error_print();
return -1;
}
if (sm4_gcm_encrypt(NULL, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != -1
|| sm4_gcm_encrypt(&sm4_key, NULL, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != -1
|| sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), NULL, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != -1
|| sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), NULL, sizeof(in), out, sizeof(tag), tag) != -1
|| sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), NULL, sizeof(tag), tag) != -1
|| sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), NULL) != -1
|| sm4_gcm_encrypt(&sm4_key, iv, 0, aad, sizeof(aad), in, sizeof(in), out, sizeof(tag), tag) != -1
|| sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, SM4_GCM_MIN_TAG_SIZE - 1, tag) != -1
|| sm4_gcm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, SM4_GCM_MAX_TAG_SIZE + 1, tag) != -1) {
error_print();
return -1;
}
if (sm4_gcm_decrypt(NULL, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, sizeof(tag), out) != -1
|| sm4_gcm_decrypt(&sm4_key, NULL, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, sizeof(tag), out) != -1
|| sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), NULL, sizeof(aad), in, sizeof(in), tag, sizeof(tag), out) != -1
|| sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), NULL, sizeof(in), tag, sizeof(tag), out) != -1
|| sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), NULL, sizeof(tag), out) != -1
|| sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, sizeof(tag), NULL) != -1
|| sm4_gcm_decrypt(&sm4_key, iv, 0, aad, sizeof(aad), in, sizeof(in), tag, sizeof(tag), out) != -1
|| sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, SM4_GCM_MIN_TAG_SIZE - 1, out) != -1
|| sm4_gcm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, SM4_GCM_MAX_TAG_SIZE + 1, out) != -1) {
error_print();
return -1;
}
if (sm4_gcm_encrypt_init(NULL, key, sizeof(key), iv, sizeof(iv), NULL, 0, sizeof(tag)) != -1
|| sm4_gcm_encrypt_init(&ctx, NULL, sizeof(key), iv, sizeof(iv), NULL, 0, sizeof(tag)) != -1
|| sm4_gcm_encrypt_init(&ctx, key, sizeof(key), NULL, sizeof(iv), NULL, 0, sizeof(tag)) != -1
|| sm4_gcm_encrypt_init(&ctx, key, sizeof(key), iv, sizeof(iv), NULL, 1, sizeof(tag)) != -1
|| sm4_gcm_encrypt_init(&ctx, key, sizeof(key) - 1, iv, sizeof(iv), NULL, 0, sizeof(tag)) != -1
|| sm4_gcm_encrypt_init(&ctx, key, sizeof(key), iv, 0, NULL, 0, sizeof(tag)) != -1
|| sm4_gcm_encrypt_init(&ctx, key, sizeof(key), iv, sizeof(iv), NULL, 0, SM4_GCM_MIN_TAG_SIZE - 1) != -1
|| sm4_gcm_encrypt_init(&ctx, key, sizeof(key), iv, sizeof(iv), NULL, 0, SM4_GCM_MAX_TAG_SIZE + 1) != -1) {
error_print();
return -1;
}
if (sm4_gcm_encrypt_init(&ctx, key, sizeof(key), iv, sizeof(iv), NULL, 0, sizeof(tag)) != 1
|| sm4_gcm_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_gcm_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_gcm_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_gcm_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_gcm_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_gcm_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_gcm_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_gcm_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_gcm_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_gcm_decrypt_init(&ctx, key, sizeof(key), iv, sizeof(iv), NULL, 0, sizeof(tag)) != 1
|| sm4_gcm_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_gcm_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_gcm_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_gcm_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_gcm_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_gcm_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_gcm_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_gcm_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_gcm_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_gcm_decrypt_encedlen_bug_vector(void)
{
SM4_GCM_CTX ctx;
const char *hex_key = "00000000000000000000000000000000";
const char *hex_iv = "000000000000000000000000";
const char *hex_cipher =
"57c880553b3a32a8322c11cb95c147a3"
"af411d0d1bd4d64302520d5045e9215c"
"dfe541de43b9feb02b9f71be2b1aef91"
"d6149e9615aa16680e4c172cc72e5930";
const char *hex_tag = "52be9a13d8a91889cf2aa124efee91f5";
uint8_t key[16];
uint8_t iv[12];
uint8_t cipher[64];
uint8_t tag[16];
uint8_t in[80];
uint8_t plain[64];
uint8_t out[80];
size_t len, keylen, ivlen, cipherlen, taglen, outlen, finlen;
hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen);
hex_to_bytes(hex_cipher, strlen(hex_cipher), cipher, &cipherlen);
hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen);
memset(plain, 0x2a, sizeof(plain));
memcpy(in, cipher, cipherlen);
memcpy(in + cipherlen, tag, taglen);
len = cipherlen + taglen;
if (keylen != sizeof(key)
|| ivlen != sizeof(iv)
|| cipherlen != sizeof(plain)
|| taglen != SM4_GCM_MAX_TAG_SIZE
|| sm4_gcm_decrypt_init(&ctx, key, keylen, iv, ivlen, NULL, 0, taglen) != 1
|| sm4_gcm_decrypt_update(&ctx, in, len, out, &outlen) != 1
|| outlen != sizeof(plain)
|| memcmp(out, plain, sizeof(plain)) != 0
|| ctx.encedlen != sizeof(plain)
|| sm4_gcm_decrypt_finish(&ctx, out + outlen, &finlen) != 1
|| finlen != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_gcm_has_flag(const TEST_SM4_GCM_VECTOR *tv, const char *flag)
{
@@ -424,6 +564,8 @@ int main(void)
if (test_sm4_gcm_gbt36624_1() != 1) goto err;
if (test_sm4_gcm_gbt36624_2() != 1) goto err;
if (test_sm4_gcm_ctx() != 1) goto err;
if (test_sm4_gcm_args() != 1) goto err;
if (test_sm4_gcm_decrypt_encedlen_bug_vector() != 1) goto err;
if (test_sm4_gcm_wycheproof() != 1) goto err;
#if ENABLE_TEST_SPEED
if (speed_sm4_gcm_encrypt() != 1) goto err;

View File

@@ -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.
@@ -246,11 +246,47 @@ static int test_sm4_ofb_ctx(void)
return 1;
}
static int test_sm4_ofb_args(void)
{
SM4_OFB_CTX ctx;
uint8_t key[16] = {0};
uint8_t iv[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
size_t outlen;
if (sm4_ofb_encrypt_init(NULL, key, iv) != -1
|| sm4_ofb_encrypt_init(&ctx, NULL, iv) != -1
|| sm4_ofb_encrypt_init(&ctx, key, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ofb_encrypt_init(&ctx, key, iv) != 1
|| sm4_ofb_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ofb_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ofb_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ofb_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ofb_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ofb_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ofb_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ofb_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ofb_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
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;
if (test_sm4_ofb_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:

View File

@@ -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.
@@ -260,10 +260,140 @@ static int test_sm4_ctr_sm3_hmac(void)
return 1;
}
static int test_sm4_cbc_sm3_hmac_args(void)
{
SM4_CBC_SM3_HMAC_CTX ctx;
uint8_t key[SM4_CBC_SM3_HMAC_KEY_SIZE] = {0};
uint8_t iv[SM4_CBC_SM3_HMAC_IV_SIZE] = {0};
uint8_t aad[16] = {0};
uint8_t in[64] = {0};
uint8_t out[128];
size_t outlen;
if (sm4_cbc_sm3_hmac_encrypt_init(NULL, key, iv, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_encrypt_init(&ctx, NULL, iv, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_encrypt_init(&ctx, key, NULL, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_encrypt_init(&ctx, key, iv, NULL, sizeof(aad)) != -1
|| sm4_cbc_sm3_hmac_decrypt_init(NULL, key, iv, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_decrypt_init(&ctx, NULL, iv, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_decrypt_init(&ctx, key, NULL, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, sizeof(aad)) != -1) {
error_print();
return -1;
}
if (sm4_cbc_sm3_hmac_encrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_cbc_sm3_hmac_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_cbc_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_cbc_sm3_hmac_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
outlen = 123;
if (sm4_cbc_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, in, 1, out, &outlen) != 1
|| outlen != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_ctr_sm3_hmac_args(void)
{
SM4_CTR_SM3_HMAC_CTX ctx;
uint8_t key[SM4_CTR_SM3_HMAC_KEY_SIZE] = {0};
uint8_t iv[SM4_CTR_SM3_HMAC_IV_SIZE] = {0};
uint8_t aad[16] = {0};
uint8_t in[64] = {0};
uint8_t out[128];
size_t outlen;
if (sm4_ctr_sm3_hmac_encrypt_init(NULL, key, iv, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_encrypt_init(&ctx, NULL, iv, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_encrypt_init(&ctx, key, NULL, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_encrypt_init(&ctx, key, iv, NULL, sizeof(aad)) != -1
|| sm4_ctr_sm3_hmac_decrypt_init(NULL, key, iv, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_decrypt_init(&ctx, NULL, iv, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_decrypt_init(&ctx, key, NULL, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, sizeof(aad)) != -1) {
error_print();
return -1;
}
if (sm4_ctr_sm3_hmac_encrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_ctr_sm3_hmac_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ctr_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_ctr_sm3_hmac_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
outlen = 123;
if (sm4_ctr_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, in, 1, out, &outlen) != 1
|| outlen != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void)
{
if (test_sm4_cbc_sm3_hmac() != 1) goto err;
if (test_sm4_ctr_sm3_hmac() != 1) goto err;
if (test_sm4_cbc_sm3_hmac_args() != 1) goto err;
if (test_sm4_ctr_sm3_hmac_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err:

View File

@@ -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.
@@ -163,10 +163,176 @@ static int test_sm4_xts_test_vectors(void)
return 1;
}
static int test_sm4_xts_ctx(void)
{
SM4_XTS_CTX ctx;
uint8_t key[32];
uint8_t iv[16];
uint8_t plaintext[64];
uint8_t ciphertext[64];
uint8_t decrypted[64];
size_t outlen, total;
rand_bytes(key, sizeof(key));
rand_bytes(iv, sizeof(iv));
rand_bytes(plaintext, sizeof(plaintext));
if (sm4_xts_encrypt_init(&ctx, key, iv, 32) != 1
|| sm4_xts_encrypt_update(&ctx, plaintext, 7, ciphertext, &outlen) != 1
|| outlen != 0
|| sm4_xts_encrypt_update(&ctx, NULL, 0, ciphertext, &outlen) != 1
|| outlen != 0
|| sm4_xts_encrypt_update(&ctx, plaintext + 7, 25, ciphertext, &outlen) != 1
|| outlen != 32) {
error_print();
return -1;
}
total = outlen;
if (sm4_xts_encrypt_update(&ctx, plaintext + 32, 32, ciphertext + total, &outlen) != 1
|| outlen != 32) {
error_print();
return -1;
}
total += outlen;
if (sm4_xts_encrypt_finish(&ctx, ciphertext + total, &outlen) != 1
|| outlen != 0
|| total != sizeof(plaintext)) {
error_print();
return -1;
}
if (sm4_xts_decrypt_init(&ctx, key, iv, 32) != 1
|| sm4_xts_decrypt_update(&ctx, ciphertext, 5, decrypted, &outlen) != 1
|| outlen != 0
|| sm4_xts_decrypt_update(&ctx, NULL, 0, decrypted, &outlen) != 1
|| outlen != 0
|| sm4_xts_decrypt_update(&ctx, ciphertext + 5, 27, decrypted, &outlen) != 1
|| outlen != 32) {
error_print();
return -1;
}
total = outlen;
if (sm4_xts_decrypt_update(&ctx, ciphertext + 32, 32, decrypted + total, &outlen) != 1
|| outlen != 32) {
error_print();
return -1;
}
total += outlen;
if (sm4_xts_decrypt_finish(&ctx, decrypted + total, &outlen) != 1
|| outlen != 0
|| total != sizeof(plaintext)
|| memcmp(decrypted, plaintext, sizeof(plaintext)) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_xts_args(void)
{
SM4_KEY key1;
SM4_KEY key2;
SM4_XTS_CTX ctx;
uint8_t key[32] = {0};
uint8_t tweak[16] = {0};
uint8_t in[32] = {0};
uint8_t out[32];
size_t outlen;
sm4_set_encrypt_key(&key1, key);
sm4_set_encrypt_key(&key2, key + 16);
if (sm4_xts_encrypt(NULL, &key2, tweak, in, sizeof(in), out) != -1
|| sm4_xts_encrypt(&key1, NULL, tweak, in, sizeof(in), out) != -1
|| sm4_xts_encrypt(&key1, &key2, NULL, in, sizeof(in), out) != -1
|| sm4_xts_encrypt(&key1, &key2, tweak, NULL, sizeof(in), out) != -1
|| sm4_xts_encrypt(&key1, &key2, tweak, in, sizeof(in), NULL) != -1
|| sm4_xts_encrypt(&key1, &key2, tweak, NULL, 0, out) != -1
|| sm4_xts_encrypt(&key1, &key2, tweak, in, SM4_BLOCK_SIZE - 1, out) != -1) {
error_print();
return -1;
}
sm4_set_decrypt_key(&key1, key);
if (sm4_xts_decrypt(NULL, &key2, tweak, in, sizeof(in), out) != -1
|| sm4_xts_decrypt(&key1, NULL, tweak, in, sizeof(in), out) != -1
|| sm4_xts_decrypt(&key1, &key2, NULL, in, sizeof(in), out) != -1
|| sm4_xts_decrypt(&key1, &key2, tweak, NULL, sizeof(in), out) != -1
|| sm4_xts_decrypt(&key1, &key2, tweak, in, sizeof(in), NULL) != -1
|| sm4_xts_decrypt(&key1, &key2, tweak, NULL, 0, out) != -1
|| sm4_xts_decrypt(&key1, &key2, tweak, in, SM4_BLOCK_SIZE - 1, out) != -1) {
error_print();
return -1;
}
if (sm4_xts_encrypt_init(NULL, key, tweak, 32) != -1
|| sm4_xts_encrypt_init(&ctx, NULL, tweak, 32) != -1
|| sm4_xts_encrypt_init(&ctx, key, NULL, 32) != -1
|| sm4_xts_encrypt_init(&ctx, key, tweak, SM4_BLOCK_SIZE - 1) != -1) {
error_print();
return -1;
}
if (sm4_xts_encrypt_init(&ctx, key, tweak, 32) != 1
|| sm4_xts_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_xts_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_xts_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_xts_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_xts_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_xts_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_xts_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_xts_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_xts_encrypt_finish(&ctx, out, NULL) != -1
|| sm4_xts_encrypt_finish(&ctx, out, &outlen) != 1
|| outlen != 0) {
error_print();
return -1;
}
if (sm4_xts_decrypt_init(NULL, key, tweak, 32) != -1
|| sm4_xts_decrypt_init(&ctx, NULL, tweak, 32) != -1
|| sm4_xts_decrypt_init(&ctx, key, NULL, 32) != -1
|| sm4_xts_decrypt_init(&ctx, key, tweak, SM4_BLOCK_SIZE - 1) != -1) {
error_print();
return -1;
}
if (sm4_xts_decrypt_init(&ctx, key, tweak, 32) != 1
|| sm4_xts_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_xts_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_xts_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_xts_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_xts_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_xts_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_xts_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_xts_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_xts_decrypt_finish(&ctx, out, NULL) != -1
|| sm4_xts_decrypt_finish(&ctx, out, &outlen) != 1
|| outlen != 0) {
error_print();
return -1;
}
if (sm4_xts_encrypt_init(&ctx, key, tweak, 32) != 1
|| sm4_xts_encrypt_update(&ctx, in, 16, out, &outlen) != 1
|| outlen != 0
|| sm4_xts_encrypt_finish(&ctx, out, &outlen) != -1) {
error_print();
return -1;
}
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;
if (test_sm4_xts_ctx() != 1) goto err;
if (test_sm4_xts_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__);
return 0;
err: