From 94fc0aacab057cf9b28219e4c9a47900f34c0a68 Mon Sep 17 00:00:00 2001 From: Zhi Guan Date: Thu, 14 Dec 2023 15:29:06 +0800 Subject: [PATCH] Update sm4test.c Fix the memcpy() bug on Windows VMs. --- tests/sm4test.c | 124 ++++++++++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 47 deletions(-) diff --git a/tests/sm4test.c b/tests/sm4test.c index 16edb93b..0f83476d 100644 --- a/tests/sm4test.c +++ b/tests/sm4test.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include @@ -553,7 +554,72 @@ static int test_sm4_cbc_update(void) return 1; } -static int test_sm4_ctr_update(void) +/* + * NOTE: + * There is an compiler bug on Tencent Cloud/Windows Server 2022/Visual Studio 2022 and GitHub CI Windows env. + * When calling memcpy(ctr, iv, sizeof(iv)) multiple times. The compiler might omit the memcpy() + * As `ctr` has been changed by sm4_ctr_encrypt() and the reset to `iv` is not working, the test will fail. + */ +static int test_sm4_ctr_update_once(void) +{ + SM4_KEY sm4_key; + SM4_CTR_CTX enc_ctx; + SM4_CTR_CTX dec_ctx; + + uint8_t key[16]; + uint8_t iv[16]; + uint8_t ctr[16]; + uint8_t mbuf[16]; + uint8_t cbuf[16]; + uint8_t pbuf[32]; + size_t mlen = 0; + size_t clen = 0; + size_t plen = 0; + size_t len; + + rand_bytes(key, sizeof(key)); + rand_bytes(iv, sizeof(iv)); + + mlen = sizeof(mbuf); + rand_bytes(mbuf, mlen); + + if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1 + || sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 + || sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { + error_print(); + return -1; + } + clen += len; + + // check ciphertext + sm4_set_encrypt_key(&sm4_key, key); + memcpy(ctr, iv, sizeof(iv)); // ctr is a variable + sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // NOTE: sm4_ctr_encrypt() change ctr value + + if (memcmp(cbuf, pbuf, clen) != 0) { + error_print(); + return -1; + } + + // check decrypt + if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1 + || sm4_ctr_encrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 + || sm4_ctr_encrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { + error_print(); + return -1; + } + plen += len; + + if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { + error_print(); + return -1; + } + + printf("%s() ok\n", __FUNCTION__); + return 1; +} + +static int test_sm4_ctr_update_multi_times(void) { SM4_KEY sm4_key; SM4_CTR_CTX enc_ctx; @@ -573,53 +639,15 @@ static int test_sm4_ctr_update(void) uint8_t *out; size_t len; size_t lens[] = { 1,5,17,80 }; + int i; rand_bytes(key, sizeof(key)); rand_bytes(iv, sizeof(iv)); - // first test - - mlen = 16; - rand_bytes(mbuf, mlen); - memcpy(ctr, iv, sizeof(iv)); - if (sm4_ctr_encrypt_init(&enc_ctx, key, ctr) != 1 - || sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1 - || sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) { - error_print(); - return -1; - } - clen += len; - - // check ciphertext - sm4_set_encrypt_key(&sm4_key, key); - sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // 注意:sm4_ctr_encrypt() 会修改ctr的值 - memcpy(ctr, iv, sizeof(iv)); - if (memcmp(cbuf, pbuf, clen) != 0) { - error_print(); - return -1; - } - - // check decrypt - if (sm4_ctr_decrypt_init(&dec_ctx, key, ctr) != 1 - || sm4_ctr_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1 - || sm4_ctr_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) { - error_print(); - return -1; - } - plen += len; - - if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) { - error_print(); - return -1; - } - - - // second test - rand_bytes(mbuf, sizeof(mbuf)); - if (sm4_ctr_encrypt_init(&enc_ctx, key, ctr) != 1) { + if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1) { error_print(); return -1; } @@ -634,9 +662,9 @@ static int test_sm4_ctr_update(void) } in += lens[i]; mlen += lens[i]; + assert(mlen <= sizeof(mbuf)); out += len; clen += len; - } if (sm4_ctr_encrypt_finish(&enc_ctx, out, &len) != 1) { error_print(); @@ -645,15 +673,16 @@ static int test_sm4_ctr_update(void) clen += len; // check ciphertest - sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); + sm4_set_encrypt_key(&sm4_key, key); memcpy(ctr, iv, sizeof(iv)); + sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); if (memcmp(pbuf, cbuf, mlen) != 0) { error_print(); return -1; } // check decrypt - if (sm4_ctr_decrypt_init(&dec_ctx, key, ctr) != 1) { + if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1) { error_print(); return -1; } @@ -670,13 +699,13 @@ static int test_sm4_ctr_update(void) out += len; plen += len; } - if (sm4_ctr_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) { + if (sm4_ctr_encrypt_update(&dec_ctx, in, clen, out, &len) != 1) { error_print(); return -1; } out += len; plen += len; - if (sm4_ctr_decrypt_finish(&dec_ctx, out, &len) != 1) { + if (sm4_ctr_encrypt_finish(&dec_ctx, out, &len) != 1) { error_print(); return -1; } @@ -701,7 +730,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_cbc_update() != 1) goto err; - if (test_sm4_ctr_update() != 1) goto err; + if (test_sm4_ctr_update_once() != 1) goto err; + if (test_sm4_ctr_update_multi_times() != 1) goto err; printf("%s all tests passed\n", __FILE__); return 0; err: