mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-07 00:46:17 +08:00
Add more SM4 test vectors
SM4 pass openssl and other known test vectors. SM4-GCM and SM4-XTS only support the GB/T GF(2^128) encoding standard.
This commit is contained in:
63
tests/rdrandtest.c
Normal file
63
tests/rdrandtest.c
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <gmssl/rdrand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
int test_rdrand(void)
|
||||
{
|
||||
const uint8_t zeros[32] = {0};
|
||||
uint8_t buf[32] = {0};
|
||||
|
||||
if (rdrand_bytes(buf, sizeof(buf)) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(buf, zeros, sizeof(zeros)) == 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test_rdseed(void)
|
||||
{
|
||||
const uint8_t zeros[32] = {0};
|
||||
uint8_t buf[32] = {0};
|
||||
|
||||
if (rdseed_bytes(buf, sizeof(buf)) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(buf, zeros, sizeof(zeros)) == 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_rdrand() != 1) goto err;
|
||||
if (test_rdseed() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
err:
|
||||
error_print();
|
||||
return 1;
|
||||
}
|
||||
331
tests/sm4_cbctest.c
Normal file
331
tests/sm4_cbctest.c
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/hex.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
static int test_sm4_cbc(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16] = {0};
|
||||
uint8_t iv[16] = {0};
|
||||
uint8_t buf1[32] = {0};
|
||||
uint8_t buf2[32] = {0};
|
||||
uint8_t buf3[32] = {0};
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
sm4_cbc_encrypt(&sm4_key, iv, buf1, 2, buf2);
|
||||
sm4_set_decrypt_key(&sm4_key, key);
|
||||
sm4_cbc_decrypt(&sm4_key, iv, buf2, 2, buf3);
|
||||
|
||||
if (memcmp(buf1, buf3, sizeof(buf3)) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_cbc_test_vectors(void)
|
||||
{
|
||||
struct {
|
||||
char *mode;
|
||||
char *key;
|
||||
char *iv;
|
||||
char *plaintext;
|
||||
char *ciphertext;
|
||||
} tests[] = {
|
||||
{
|
||||
"openssl-1",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210",
|
||||
"2677f46b09c122cc975533105bd4a22af6125f7275ce552c3a2bbcf533de8a3b",
|
||||
},
|
||||
{
|
||||
"openssl-2",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210",
|
||||
"2677f46b09c122cc975533105bd4a22af6125f7275ce552c3a2bbcf533de8a3bfff5a4f208092c0901ba02d5772977369915e3fa2356c9f4eb6460ecc457e7f8e3cfa3deebfe9883e3a48bcf7c4a11aa3ec9e0d317c5d319be72a5cdddec640c",
|
||||
},
|
||||
{
|
||||
"openssl-3",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210",
|
||||
"2677f46b09c122cc975533105bd4a22af6125f7275ce552c3a2bbcf533de8a3bfff5a4f208092c0901ba02d5772977369915e3fa2356c9f4eb6460ecc457e7f8e3cfa3deebfe9883e3a48bcf7c4a11aa3ec9e0d317c5d319be72a5cdddec640c6fc70bfa3ddaafffdd7c09b2774dcb2cec29f0c6f0b6773e985b3e395e924238505a8f120d9ca84de5c3cf7e45f097b14b3a46c5b1068669982a5c1f5f61be291b984f331d44ffb2758f771672448fc957fa1416c446427a41e25d5524a2418b9d96b2f17582f0f1aa9c204c6807f54f7b6833c5f00856659ddabc245936868c",
|
||||
},
|
||||
};
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16];
|
||||
uint8_t iv[16];
|
||||
size_t key_len;
|
||||
size_t iv_len;
|
||||
uint8_t *plaintext;
|
||||
size_t plaintext_len;
|
||||
uint8_t *ciphertext;
|
||||
size_t ciphertext_len;
|
||||
uint8_t *encrypted;
|
||||
size_t encrypted_len;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
|
||||
|
||||
if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len);
|
||||
hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len);
|
||||
|
||||
if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
sm4_cbc_encrypt(&sm4_key, iv, plaintext, plaintext_len/16, encrypted);
|
||||
|
||||
if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(encrypted);
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_cbc_padding(void)
|
||||
{
|
||||
SM4_KEY enc_key;
|
||||
SM4_KEY dec_key;
|
||||
uint8_t key[16] = {0};
|
||||
uint8_t iv[16] = {0};
|
||||
uint8_t buf1[64];
|
||||
uint8_t buf2[128];
|
||||
uint8_t buf3[128];
|
||||
size_t len1, len2, len3;
|
||||
|
||||
sm4_set_encrypt_key(&enc_key, key);
|
||||
sm4_set_decrypt_key(&dec_key, key);
|
||||
|
||||
len1 = 0;
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len1 = 7;
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len1 = 16;
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len1 = 33;
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len1 = sizeof(buf1);
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_cbc_ctx(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
SM4_CBC_CTX enc_ctx;
|
||||
SM4_CBC_CTX dec_ctx;
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t mbuf[16 * 10];
|
||||
uint8_t cbuf[16 * 11];
|
||||
uint8_t pbuf[16 * 11];
|
||||
size_t mlen = 0;
|
||||
size_t clen = 0;
|
||||
size_t plen = 0;
|
||||
|
||||
uint8_t *in;
|
||||
uint8_t *out;
|
||||
size_t len;
|
||||
size_t lens[] = { 1,5,17,80 };
|
||||
int i;
|
||||
|
||||
rand_bytes(key, sizeof(key));
|
||||
rand_bytes(iv, sizeof(iv));
|
||||
|
||||
|
||||
|
||||
// first test
|
||||
|
||||
mlen = 16;
|
||||
rand_bytes(mbuf, mlen);
|
||||
|
||||
if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1
|
||||
|| sm4_cbc_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1
|
||||
|| sm4_cbc_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
clen += len;
|
||||
|
||||
// check ciphertext
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen);
|
||||
if (clen != plen || memcmp(cbuf, pbuf, plen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check decrypt
|
||||
if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1
|
||||
|| sm4_cbc_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1
|
||||
|| sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen += len;
|
||||
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// second test
|
||||
|
||||
rand_bytes(mbuf, sizeof(mbuf));
|
||||
|
||||
if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in = mbuf;
|
||||
out = cbuf;
|
||||
mlen = 0;
|
||||
clen = 0;
|
||||
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
|
||||
if (sm4_cbc_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in += lens[i];
|
||||
mlen += lens[i];
|
||||
out += len;
|
||||
clen += len;
|
||||
|
||||
}
|
||||
if (sm4_cbc_encrypt_finish(&enc_ctx, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
clen += len;
|
||||
|
||||
// check ciphertest
|
||||
sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen);
|
||||
if (plen != clen || memcmp(pbuf, cbuf, clen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check decrypt
|
||||
if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen = 0;
|
||||
in = cbuf;
|
||||
out = pbuf;
|
||||
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
|
||||
if (sm4_cbc_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in += lens[i];
|
||||
clen -= lens[i];
|
||||
out += len;
|
||||
plen += len;
|
||||
}
|
||||
if (sm4_cbc_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
out += len;
|
||||
plen += len;
|
||||
if (sm4_cbc_decrypt_finish(&dec_ctx, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen += len;
|
||||
|
||||
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_sm4_cbc() != 1) goto err;
|
||||
if (test_sm4_cbc_test_vectors() != 1) goto err;
|
||||
if (test_sm4_cbc_padding() != 1) goto err;
|
||||
if (test_sm4_cbc_ctx() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
err:
|
||||
error_print();
|
||||
return 1;
|
||||
}
|
||||
@@ -65,9 +65,121 @@ static int test_sm4_ccm(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ccm_test_vectors(void)
|
||||
{
|
||||
struct {
|
||||
char *label;
|
||||
char *key;
|
||||
char *iv;
|
||||
char *aad;
|
||||
char *tag;
|
||||
char *plaintext;
|
||||
char *ciphertext;
|
||||
} tests[] = {
|
||||
{
|
||||
"rfc8998",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"00001234567800000000abcd",
|
||||
"feedfacedeadbeeffeedfacedeadbeefabaddad2",
|
||||
"16842d4fa186f56ab33256971fa110f4",
|
||||
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa",
|
||||
"48af93501fa62adbcd414cce6034d895dda1bf8f132f042098661572e7483094fd12e518ce062c98acee28d95df4416bed31a2f04476c18bb40c84a74b97dc5b",
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t key[16];
|
||||
size_t key_len;
|
||||
uint8_t iv[16];
|
||||
size_t iv_len;
|
||||
uint8_t *aad;
|
||||
size_t aad_len;
|
||||
uint8_t tag[16];
|
||||
size_t tag_len;
|
||||
uint8_t *plaintext;
|
||||
size_t plaintext_len;
|
||||
uint8_t *ciphertext;
|
||||
size_t ciphertext_len;
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t *encrypted;
|
||||
size_t encrypted_len;
|
||||
uint8_t *decrypted;
|
||||
size_t decrypted_len;
|
||||
uint8_t mac[16];
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
|
||||
|
||||
if ((aad = (uint8_t *)malloc(strlen(tests[i].aad)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
hex_to_bytes(tests[i].aad, strlen(tests[i].aad), aad, &aad_len);
|
||||
hex_to_bytes(tests[i].tag, strlen(tests[i].tag), tag, &tag_len);
|
||||
hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len);
|
||||
hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len);
|
||||
|
||||
if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
if (sm4_ccm_encrypt(&sm4_key, iv, iv_len, aad, aad_len,
|
||||
plaintext, plaintext_len, encrypted, tag_len, mac) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(mac, tag, tag_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//sm4_set_encrypt_key(&sm4_key, key); // same as ccm_encrypt
|
||||
if (sm4_ccm_decrypt(&sm4_key, iv, iv_len, aad, aad_len,
|
||||
ciphertext, ciphertext_len, tag, tag_len, decrypted) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(decrypted, plaintext, plaintext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(aad);
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(encrypted);
|
||||
free(decrypted);
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_sm4_ccm() != 1) goto err;
|
||||
if (test_sm4_ccm_test_vectors() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
err:
|
||||
|
||||
@@ -59,6 +59,113 @@ static int test_sm4_cfb(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
// FIXME: no test vectors for SM4_CFB_8, SM4_CFB_64
|
||||
static int test_sm4_cfb_test_vectors(void)
|
||||
{
|
||||
struct {
|
||||
char *label;
|
||||
char *key;
|
||||
size_t sbytes;
|
||||
char *iv;
|
||||
char *plaintext;
|
||||
char *ciphertext;
|
||||
} tests[] = {
|
||||
{
|
||||
"openssl",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
SM4_CFB_128,
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210",
|
||||
"693d9a535bad5bb1786f53d7253a70569ed258a85a0467cc92aab393dd978995",
|
||||
},
|
||||
{
|
||||
"draft-ribose-cfrg-sm4-10 example-1",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
SM4_CFB_128,
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffaaaaaaaabbbbbbbb",
|
||||
"ac3236cb861dd316e6413b4e3c7524b769d4c54ed433b9a0346009beb37b2b3f",
|
||||
},
|
||||
{
|
||||
"draft-ribose-cfrg-sm4-10 example-2",
|
||||
"fedcba98765432100123456789abcdef",
|
||||
SM4_CFB_128,
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffaaaaaaaabbbbbbbb",
|
||||
"5dcccd25a84ba16560d7f265887068490d9b86ff20c3bfe115ffa02ca6192cc5"
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t key[16];
|
||||
size_t key_len;
|
||||
uint8_t iv[16];
|
||||
size_t iv_len;
|
||||
uint8_t *plaintext;
|
||||
size_t plaintext_len;
|
||||
uint8_t *ciphertext;
|
||||
size_t ciphertext_len;
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t *encrypted;
|
||||
size_t encrypted_len;
|
||||
uint8_t *decrypted;
|
||||
size_t decrypted_len;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
|
||||
|
||||
|
||||
if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len);
|
||||
hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len);
|
||||
|
||||
if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
sm4_cfb_encrypt(&sm4_key, tests[i].sbytes, iv, plaintext, plaintext_len, encrypted);
|
||||
|
||||
if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//sm4_set_encrypt_key(&sm4_key, key);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
sm4_cfb_decrypt(&sm4_key, tests[i].sbytes, iv, ciphertext, ciphertext_len, decrypted);
|
||||
|
||||
if (memcmp(decrypted, plaintext, plaintext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(encrypted);
|
||||
free(decrypted);
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_cfb_ctx(void)
|
||||
{
|
||||
|
||||
@@ -158,6 +265,7 @@ static int test_sm4_cfb_ctx(void)
|
||||
int main(void)
|
||||
{
|
||||
if (test_sm4_cfb() != 1) goto err;
|
||||
if (test_sm4_cfb_test_vectors() != 1) goto err;
|
||||
if (test_sm4_cfb_ctx() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
|
||||
373
tests/sm4_ctrtest.c
Normal file
373
tests/sm4_ctrtest.c
Normal file
@@ -0,0 +1,373 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/hex.h>
|
||||
#include <gmssl/rand.h>
|
||||
#include <gmssl/error.h>
|
||||
|
||||
|
||||
static int test_sm4_ctr(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16] = {0};
|
||||
uint8_t ctr[16];
|
||||
uint8_t buf1[30] = {0};
|
||||
uint8_t buf2[30] = {0};
|
||||
uint8_t buf3[30] = {0};
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
memset(ctr, 0, sizeof(ctr));
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2);
|
||||
|
||||
memset(ctr, 0, sizeof(ctr));
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, buf2, sizeof(buf2), buf3);
|
||||
|
||||
if (memcmp(buf1, buf3, sizeof(buf3)) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ctr_test_vectors(void)
|
||||
{
|
||||
struct {
|
||||
char *label;
|
||||
char *key;
|
||||
char *iv;
|
||||
char *plaintext;
|
||||
char *ciphertext;
|
||||
} tests[] = {
|
||||
{
|
||||
"openssl-1",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa",
|
||||
"c2b4759e78ac3cf43d0852f4e8d5f9fd7256e8a5fcb65a350ee00630912e44492a0b17e1b85b060d0fba612d8a95831638b361fd5ffacd942f081485a83ca35d",
|
||||
},
|
||||
{
|
||||
"draft-ribose-cfrg-sm4-10 example-1",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb",
|
||||
"ac3236cb970cc20791364c395a1342d1a3cbc1878c6f30cd074cce385cdd70c7f234bc0e24c11980fd1286310ce37b926e02fcd0faa0baf38b2933851d824514",
|
||||
},
|
||||
{
|
||||
"draft-ribose-cfrg-sm4-10 example-2",
|
||||
"fedcba98765432100123456789abcdef",
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbb",
|
||||
"5dcccd25b95ab07417a08512ee160e2f8f661521cbbab44cc87138445bc29e5c0ae0297205d62704173b21239b887f6c8cb5b800917a2488284bde9e16ea2906",
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t key[16];
|
||||
size_t key_len;
|
||||
uint8_t iv[16];
|
||||
size_t iv_len;
|
||||
uint8_t *plaintext;
|
||||
size_t plaintext_len;
|
||||
uint8_t *ciphertext;
|
||||
size_t ciphertext_len;
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t *encrypted;
|
||||
size_t encrypted_len;
|
||||
uint8_t *decrypted;
|
||||
size_t decrypted_len;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
|
||||
|
||||
if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len);
|
||||
hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len);
|
||||
|
||||
if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
sm4_ctr_encrypt(&sm4_key, iv, plaintext, plaintext_len, encrypted);
|
||||
|
||||
if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
//sm4_set_encrypt_key(&sm4_key, key);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
sm4_ctr_encrypt(&sm4_key, iv, ciphertext, ciphertext_len, decrypted);
|
||||
|
||||
if (memcmp(decrypted, plaintext, plaintext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(encrypted);
|
||||
free(decrypted);
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ctr_with_carray(void)
|
||||
{
|
||||
const char *hex_key = "0123456789ABCDEFFEDCBA9876543210";
|
||||
const char *hex_ctr = "0000000000000000000000000000FFFF";
|
||||
const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"
|
||||
"CCCCCCCCCCCCCCCCDDDDDDDDDDDD";
|
||||
const char *hex_out = "7EA678F9F0CBE2000917C63D4E77B4C8"
|
||||
"6E4E8532B0046E4AC1E97DA8B831";
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16] = {0};
|
||||
uint8_t ctr[16];
|
||||
uint8_t buf1[30] = {0};
|
||||
uint8_t buf2[30] = {0};
|
||||
uint8_t buf3[30] = {0};
|
||||
|
||||
size_t keylen, ctrlen, inlen, outlen;
|
||||
|
||||
hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
|
||||
hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen);
|
||||
hex_to_bytes(hex_in, strlen(hex_in), buf1, &inlen);
|
||||
hex_to_bytes(hex_out, strlen(hex_out), buf3, &outlen);
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2);
|
||||
|
||||
if (memcmp(buf2, buf3, sizeof(buf3)) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen);
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, buf3, sizeof(buf3), buf2);
|
||||
|
||||
if (memcmp(buf2, buf1, sizeof(buf1)) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* There is an compiler bug on Tencent Cloud/Windows Server 2022/Visual Studio 2022 and GitHub CI Windows env.
|
||||
* When calling memcpy(ctr, iv, sizeof(iv)) multiple times. The compiler might omit the memcpy()
|
||||
* As `ctr` has been changed by sm4_ctr_encrypt() and the reset to `iv` is not working, the test will fail.
|
||||
*/
|
||||
static int test_sm4_ctr_ctx(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
SM4_CTR_CTX enc_ctx;
|
||||
SM4_CTR_CTX dec_ctx;
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t ctr[16];
|
||||
uint8_t mbuf[16];
|
||||
uint8_t cbuf[16];
|
||||
uint8_t pbuf[32];
|
||||
size_t mlen = 0;
|
||||
size_t clen = 0;
|
||||
size_t plen = 0;
|
||||
size_t len;
|
||||
|
||||
rand_bytes(key, sizeof(key));
|
||||
rand_bytes(iv, sizeof(iv));
|
||||
|
||||
mlen = sizeof(mbuf);
|
||||
rand_bytes(mbuf, mlen);
|
||||
|
||||
if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1
|
||||
|| sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1
|
||||
|| sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
clen += len;
|
||||
|
||||
// check ciphertext
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
memcpy(ctr, iv, sizeof(iv)); // ctr is a variable
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // NOTE: sm4_ctr_encrypt() change ctr value
|
||||
|
||||
if (memcmp(cbuf, pbuf, clen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check decrypt
|
||||
if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1
|
||||
|| sm4_ctr_encrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1
|
||||
|| sm4_ctr_encrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen += len;
|
||||
|
||||
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ctr_ctx_multi_updates(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
SM4_CTR_CTX enc_ctx;
|
||||
SM4_CTR_CTX dec_ctx;
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t ctr[16];
|
||||
uint8_t mbuf[16 * 10];
|
||||
uint8_t cbuf[16 * 11];
|
||||
uint8_t pbuf[16 * 11];
|
||||
size_t mlen = 0;
|
||||
size_t clen = 0;
|
||||
size_t plen = 0;
|
||||
|
||||
uint8_t *in;
|
||||
uint8_t *out;
|
||||
size_t len;
|
||||
size_t lens[] = { 1,5,17,80 };
|
||||
|
||||
int i;
|
||||
|
||||
rand_bytes(key, sizeof(key));
|
||||
rand_bytes(iv, sizeof(iv));
|
||||
|
||||
rand_bytes(mbuf, sizeof(mbuf));
|
||||
|
||||
if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in = mbuf;
|
||||
out = cbuf;
|
||||
mlen = 0;
|
||||
clen = 0;
|
||||
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
|
||||
if (sm4_ctr_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in += lens[i];
|
||||
mlen += lens[i];
|
||||
if (mlen > sizeof(mbuf)) {
|
||||
// invalid lens[] values, reset the test data
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
out += len;
|
||||
clen += len;
|
||||
}
|
||||
if (sm4_ctr_encrypt_finish(&enc_ctx, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
clen += len;
|
||||
|
||||
// check ciphertest
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
memcpy(ctr, iv, sizeof(iv));
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf);
|
||||
if (memcmp(pbuf, cbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check decrypt
|
||||
if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen = 0;
|
||||
in = cbuf;
|
||||
out = pbuf;
|
||||
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
|
||||
if (sm4_ctr_encrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in += lens[i];
|
||||
clen -= lens[i];
|
||||
out += len;
|
||||
plen += len;
|
||||
}
|
||||
if (sm4_ctr_encrypt_update(&dec_ctx, in, clen, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
out += len;
|
||||
plen += len;
|
||||
if (sm4_ctr_encrypt_finish(&dec_ctx, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen += len;
|
||||
|
||||
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_sm4_ctr() != 1) goto err;
|
||||
if (test_sm4_ctr_test_vectors() != 1) goto err;
|
||||
if (test_sm4_ctr_with_carray() != 1) goto err;
|
||||
if (test_sm4_ctr_ctx() != 1) goto err;
|
||||
if (test_sm4_ctr_ctx_multi_updates() != 1) goto err;
|
||||
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
err:
|
||||
error_print();
|
||||
return 1;
|
||||
}
|
||||
@@ -47,7 +47,7 @@ static int test_sm4_ecb(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ecb_testvec(void)
|
||||
static int test_sm4_ecb_test_vectors(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16] = {
|
||||
@@ -180,11 +180,10 @@ static int test_sm4_ecb_ctx(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_sm4_ecb() != 1) goto err;
|
||||
if (test_sm4_ecb_testvec() != 1) goto err;
|
||||
if (test_sm4_ecb_test_vectors() != 1) goto err;
|
||||
if (test_sm4_ecb_ctx() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
|
||||
@@ -196,7 +196,7 @@ static int test_sm4_gcm_gbt36624_2(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_gcm_update(void)
|
||||
static int test_sm4_gcm_ctx(void)
|
||||
{
|
||||
SM4_GCM_CTX aead_ctx;
|
||||
uint8_t key[16];
|
||||
@@ -317,7 +317,7 @@ int main(void)
|
||||
if (test_sm4_gcm() != 1) goto err;
|
||||
if (test_sm4_gcm_gbt36624_1() != 1) goto err;
|
||||
if (test_sm4_gcm_gbt36624_2() != 1) goto err;
|
||||
if (test_sm4_gcm_update() != 1) goto err;
|
||||
if (test_sm4_gcm_ctx() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
err:
|
||||
|
||||
@@ -55,6 +55,107 @@ static int test_sm4_ofb(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ofb_test_vectors(void)
|
||||
{
|
||||
struct {
|
||||
char *label;
|
||||
char *key;
|
||||
char *iv;
|
||||
char *plaintext;
|
||||
char *ciphertext;
|
||||
} tests[] = {
|
||||
{
|
||||
"sm4-ofb from openssl",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"0123456789abcdeffedcba98765432100123456789abcdeffedcba9876543210",
|
||||
"693d9a535bad5bb1786f53d7253a7056f2075d28b5235f58d50027e4177d2bce",
|
||||
},
|
||||
{
|
||||
"sm4-ofb-example-1 from draft-ribose-cfrg-sm4-10",
|
||||
"0123456789abcdeffedcba9876543210",
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffaaaaaaaabbbbbbbb",
|
||||
"ac3236cb861dd316e6413b4e3c7524b71d01aca2487ca582cbf5463e6698539b",
|
||||
},
|
||||
{
|
||||
"sm4-ofb-example-2 from draft-ribose-cfrg-sm4-10",
|
||||
"fedcba98765432100123456789abcdef",
|
||||
"000102030405060708090a0b0c0d0e0f",
|
||||
"aaaaaaaabbbbbbbbccccccccddddddddeeeeeeeeffffffffaaaaaaaabbbbbbbb",
|
||||
"5dcccd25a84ba16560d7f2658870684933fa16bd5cd9c856cacaa1e101897a97",
|
||||
},
|
||||
};
|
||||
|
||||
uint8_t key[16];
|
||||
size_t key_len;
|
||||
uint8_t iv[16];
|
||||
size_t iv_len;
|
||||
uint8_t *plaintext;
|
||||
size_t plaintext_len;
|
||||
uint8_t *ciphertext;
|
||||
size_t ciphertext_len;
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t *encrypted;
|
||||
size_t encrypted_len;
|
||||
uint8_t *decrypted;
|
||||
size_t decrypted_len;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
|
||||
|
||||
|
||||
if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len);
|
||||
hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len);
|
||||
|
||||
if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
sm4_ofb_encrypt(&sm4_key, iv, plaintext, plaintext_len, encrypted);
|
||||
|
||||
if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
sm4_ofb_encrypt(&sm4_key, iv, ciphertext, ciphertext_len, decrypted);
|
||||
|
||||
if (memcmp(decrypted, plaintext, plaintext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(encrypted);
|
||||
free(decrypted);
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ofb_ctx(void)
|
||||
{
|
||||
SM4_OFB_CTX ctx;
|
||||
@@ -150,6 +251,7 @@ static int test_sm4_ofb_ctx(void)
|
||||
int main(void)
|
||||
{
|
||||
if (test_sm4_ofb() != 1) goto err;
|
||||
if (test_sm4_ofb_test_vectors() != 1) goto err;
|
||||
if (test_sm4_ofb_ctx() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
|
||||
@@ -54,9 +54,118 @@ static int test_sm4_xts(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_xts_test_vectors(void)
|
||||
{
|
||||
struct {
|
||||
char *label;
|
||||
char *key;
|
||||
char *iv;
|
||||
char *plaintext;
|
||||
char *ciphertext;
|
||||
} tests[] = {
|
||||
{
|
||||
"https://github.com/mewmix/sm4-xts-openssl",
|
||||
"68d90424687cc2043595091a78a44ec2c639c3ecc6b14d7ac42ce74e582fa3dc",
|
||||
"601cd97ddeb1c75bbe5865072f3dc7a8",
|
||||
"686579667269656e64736c657473676574656e6372797074656421",
|
||||
"34143fbf6cb3a97feb84f866d85e01f8d15ed03905552cb12cd567",
|
||||
},
|
||||
{
|
||||
"openssl-1 (openssl/test/recipes/30-test_evp_data/evpciph_sm4.txt)",
|
||||
"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f",
|
||||
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
|
||||
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17",
|
||||
"e9538251c71d7b80bbe4483fef497bd12c5c581bd6242fc51e08964fb4f60fdb0ba42f63499279213d318d2c11f6886e903be7f93a1b3479",
|
||||
},
|
||||
{
|
||||
"openssl-2",
|
||||
"2b7e151628aed2a6abf7158809cf4f3c000102030405060708090a0b0c0d0e0f",
|
||||
"f0f1f2f3f4f5f6f7f8f9fafbfcfdfeff",
|
||||
"6bc1bee22e409f96e93d7e117393172aae2d8a571e03ac9c9eb76fac45af8e5130c81c46a35ce411e5fbc1191a0a52eff69f2445df4f9b17",
|
||||
"e9538251c71d7b80bbe4483fef497bd12c5c581bd6242fc51e08964fb4f60fdb0ba42f63499279213d318d2c11f6886e903be7f93a1b3479",
|
||||
},
|
||||
};
|
||||
|
||||
SM4_KEY sm4_key1;
|
||||
SM4_KEY sm4_key2;
|
||||
|
||||
uint8_t key[32];
|
||||
size_t key_len;
|
||||
uint8_t iv[16];
|
||||
size_t iv_len;
|
||||
uint8_t *aad;
|
||||
size_t aad_len;
|
||||
uint8_t tag[16];
|
||||
size_t tag_len;
|
||||
uint8_t *plaintext;
|
||||
size_t plaintext_len;
|
||||
uint8_t *ciphertext;
|
||||
size_t ciphertext_len;
|
||||
|
||||
uint8_t *encrypted;
|
||||
size_t encrypted_len;
|
||||
uint8_t *decrypted;
|
||||
size_t decrypted_len;
|
||||
size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++) {
|
||||
|
||||
if ((plaintext = (uint8_t *)malloc(strlen(tests[i].plaintext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((ciphertext = (uint8_t *)malloc(strlen(tests[i].ciphertext)/2)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
hex_to_bytes(tests[i].key, strlen(tests[i].key), key, &key_len);
|
||||
hex_to_bytes(tests[i].iv, strlen(tests[i].iv), iv, &iv_len);
|
||||
hex_to_bytes(tests[i].plaintext, strlen(tests[i].plaintext), plaintext, &plaintext_len);
|
||||
hex_to_bytes(tests[i].ciphertext, strlen(tests[i].ciphertext), ciphertext, &ciphertext_len);
|
||||
|
||||
if ((encrypted = (uint8_t *)malloc(ciphertext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if ((decrypted = (uint8_t *)malloc(plaintext_len)) == NULL) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key1, key);
|
||||
sm4_set_encrypt_key(&sm4_key2, key + 16);
|
||||
|
||||
if (sm4_xts_encrypt(&sm4_key1, &sm4_key2, iv, plaintext, plaintext_len, encrypted) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(encrypted, ciphertext, ciphertext_len) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
sm4_set_decrypt_key(&sm4_key1, key);
|
||||
sm4_set_encrypt_key(&sm4_key2, key + 16);
|
||||
if (sm4_xts_decrypt(&sm4_key1, &sm4_key2, iv, ciphertext, ciphertext_len, decrypted) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
free(plaintext);
|
||||
free(ciphertext);
|
||||
free(encrypted);
|
||||
free(decrypted);
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
if (test_sm4_xts() != 1) goto err;
|
||||
if (test_sm4_xts_test_vectors() != 1) goto err;
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
err:
|
||||
|
||||
636
tests/sm4test.c
636
tests/sm4test.c
@@ -90,648 +90,24 @@ static int test_sm4(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_cbc(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16] = {0};
|
||||
uint8_t iv[16] = {0};
|
||||
uint8_t buf1[32] = {0};
|
||||
uint8_t buf2[32] = {0};
|
||||
uint8_t buf3[32] = {0};
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
sm4_cbc_encrypt(&sm4_key, iv, buf1, 2, buf2);
|
||||
sm4_set_decrypt_key(&sm4_key, key);
|
||||
sm4_cbc_decrypt(&sm4_key, iv, buf2, 2, buf3);
|
||||
|
||||
if (memcmp(buf1, buf3, sizeof(buf3)) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_cbc_padding(void)
|
||||
{
|
||||
SM4_KEY enc_key;
|
||||
SM4_KEY dec_key;
|
||||
uint8_t key[16] = {0};
|
||||
uint8_t iv[16] = {0};
|
||||
uint8_t buf1[64];
|
||||
uint8_t buf2[128];
|
||||
uint8_t buf3[128];
|
||||
size_t len1, len2, len3;
|
||||
|
||||
sm4_set_encrypt_key(&enc_key, key);
|
||||
sm4_set_decrypt_key(&dec_key, key);
|
||||
|
||||
len1 = 0;
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len1 = 7;
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len1 = 16;
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len1 = 33;
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
len1 = sizeof(buf1);
|
||||
sm4_cbc_padding_encrypt(&enc_key, iv, buf1, len1, buf2, &len2);
|
||||
sm4_cbc_padding_decrypt(&dec_key, iv, buf2, len2, buf3, &len3);
|
||||
if (len1 != len3 || memcmp(buf1, buf3, len3) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ctr(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16] = {0};
|
||||
uint8_t ctr[16];
|
||||
uint8_t buf1[30] = {0};
|
||||
uint8_t buf2[30] = {0};
|
||||
uint8_t buf3[30] = {0};
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
memset(ctr, 0, sizeof(ctr));
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2);
|
||||
|
||||
memset(ctr, 0, sizeof(ctr));
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, buf2, sizeof(buf2), buf3);
|
||||
|
||||
if (memcmp(buf1, buf3, sizeof(buf3)) != 0) {
|
||||
fprintf(stderr, "%s %d: error\n", __FILE__, __LINE__);
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ctr_with_carray(void)
|
||||
{
|
||||
const char *hex_key = "0123456789ABCDEFFEDCBA9876543210";
|
||||
const char *hex_ctr = "0000000000000000000000000000FFFF";
|
||||
const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"
|
||||
"CCCCCCCCCCCCCCCCDDDDDDDDDDDD";
|
||||
const char *hex_out = "7EA678F9F0CBE2000917C63D4E77B4C8"
|
||||
"6E4E8532B0046E4AC1E97DA8B831";
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16] = {0};
|
||||
uint8_t ctr[16];
|
||||
uint8_t buf1[30] = {0};
|
||||
uint8_t buf2[30] = {0};
|
||||
uint8_t buf3[30] = {0};
|
||||
|
||||
size_t keylen, ctrlen, inlen, outlen;
|
||||
|
||||
hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
|
||||
hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen);
|
||||
hex_to_bytes(hex_in, strlen(hex_in), buf1, &inlen);
|
||||
hex_to_bytes(hex_out, strlen(hex_out), buf3, &outlen);
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, buf1, sizeof(buf1), buf2);
|
||||
|
||||
if (memcmp(buf2, buf3, sizeof(buf3)) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
hex_to_bytes(hex_ctr, strlen(hex_ctr), ctr, &ctrlen);
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, buf3, sizeof(buf3), buf2);
|
||||
|
||||
if (memcmp(buf2, buf1, sizeof(buf1)) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_gcm(void)
|
||||
{
|
||||
// gcm test vectors from rfc 8998 A.1
|
||||
const char *hex_key = "0123456789ABCDEFFEDCBA9876543210";
|
||||
const char *hex_iv = "00001234567800000000ABCD";
|
||||
const char *hex_aad = "FEEDFACEDEADBEEFFEEDFACEDEADBEEF"
|
||||
"ABADDAD2";
|
||||
const char *hex_in = "AAAAAAAAAAAAAAAABBBBBBBBBBBBBBBB"
|
||||
"CCCCCCCCCCCCCCCCDDDDDDDDDDDDDDDD"
|
||||
"EEEEEEEEEEEEEEEEFFFFFFFFFFFFFFFF"
|
||||
"EEEEEEEEEEEEEEEEAAAAAAAAAAAAAAAA";
|
||||
const char *hex_out = "17F399F08C67D5EE19D0DC9969C4BB7D"
|
||||
"5FD46FD3756489069157B282BB200735"
|
||||
"D82710CA5C22F0CCFA7CBF93D496AC15"
|
||||
"A56834CBCF98C397B4024A2691233B8D";
|
||||
const char *hex_tag = "83DE3541E4C2B58177E065A9BF7B62EC";
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16];
|
||||
uint8_t iv[12];
|
||||
uint8_t aad[20];
|
||||
uint8_t in[64];
|
||||
uint8_t out[64];
|
||||
uint8_t tag[16];
|
||||
size_t keylen, ivlen, aadlen, inlen, outlen, taglen;
|
||||
|
||||
uint8_t buf[64];
|
||||
uint8_t mac[16];
|
||||
|
||||
hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
|
||||
hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen);
|
||||
hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen);
|
||||
hex_to_bytes(hex_in, strlen(hex_in), in, &inlen);
|
||||
hex_to_bytes(hex_out, strlen(hex_out), out, &outlen);
|
||||
hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(mac, 0, sizeof(mac));
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
|
||||
// test gcm encrypt
|
||||
sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac);
|
||||
if (memcmp(buf, out, outlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(mac, tag, taglen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// test gcm decrypt
|
||||
memset(buf, 0, sizeof(buf));
|
||||
sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf);
|
||||
if (memcmp(buf, in, inlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_gcm_gbt36624_1(void)
|
||||
{
|
||||
// gcm test vectors from GB/T 36624-2018 C.5
|
||||
const char *hex_key = "00000000000000000000000000000000";
|
||||
const char *hex_iv = "000000000000000000000000";
|
||||
const char *hex_aad = "";
|
||||
const char *hex_in = "";
|
||||
const char *hex_out = "";
|
||||
const char *hex_tag = "232F0CFE308B49EA6FC88229B5DC858D";
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16];
|
||||
uint8_t iv[12];
|
||||
uint8_t aad[20];
|
||||
uint8_t in[64];
|
||||
uint8_t out[64];
|
||||
uint8_t tag[16];
|
||||
size_t keylen, ivlen, aadlen, inlen, outlen, taglen;
|
||||
|
||||
uint8_t buf[64];
|
||||
uint8_t mac[16];
|
||||
|
||||
hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
|
||||
hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen);
|
||||
hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen);
|
||||
hex_to_bytes(hex_in, strlen(hex_in), in, &inlen);
|
||||
hex_to_bytes(hex_out, strlen(hex_out), out, &outlen);
|
||||
hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(mac, 0, sizeof(mac));
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
|
||||
// test gcm encrypt
|
||||
sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac);
|
||||
if (memcmp(buf, out, outlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(mac, tag, taglen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// test gcm decrypt
|
||||
memset(buf, 0, sizeof(buf));
|
||||
sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf);
|
||||
if (memcmp(buf, in, inlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_gcm_gbt36624_2(void)
|
||||
{
|
||||
// gcm test vectors from GB/T 36624-2018 C.5
|
||||
const char *hex_key = "00000000000000000000000000000000";
|
||||
const char *hex_iv = "000000000000000000000000";
|
||||
const char *hex_aad = "";
|
||||
const char *hex_in = "00000000000000000000000000000000";
|
||||
const char *hex_out = "7DE2AA7F1110188218063BE1BFEB6D89";
|
||||
const char *hex_tag = "B851B5F39493752BE508F1BB4482C557";
|
||||
|
||||
SM4_KEY sm4_key;
|
||||
uint8_t key[16];
|
||||
uint8_t iv[12];
|
||||
uint8_t aad[20];
|
||||
uint8_t in[64];
|
||||
uint8_t out[64];
|
||||
uint8_t tag[16];
|
||||
size_t keylen, ivlen, aadlen, inlen, outlen, taglen;
|
||||
|
||||
uint8_t buf[64];
|
||||
uint8_t mac[16];
|
||||
|
||||
hex_to_bytes(hex_key, strlen(hex_key), key, &keylen);
|
||||
hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen);
|
||||
hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen);
|
||||
hex_to_bytes(hex_in, strlen(hex_in), in, &inlen);
|
||||
hex_to_bytes(hex_out, strlen(hex_out), out, &outlen);
|
||||
hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen);
|
||||
|
||||
memset(buf, 0, sizeof(buf));
|
||||
memset(mac, 0, sizeof(mac));
|
||||
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
|
||||
// test gcm encrypt
|
||||
sm4_gcm_encrypt(&sm4_key, iv, ivlen, aad, aadlen, in, inlen, buf, taglen, mac);
|
||||
if (memcmp(buf, out, outlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (memcmp(mac, tag, taglen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// test gcm decrypt
|
||||
memset(buf, 0, sizeof(buf));
|
||||
sm4_gcm_decrypt(&sm4_key, iv, ivlen, aad, aadlen, out, outlen, tag, taglen, buf);
|
||||
if (memcmp(buf, in, inlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_cbc_update(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
SM4_CBC_CTX enc_ctx;
|
||||
SM4_CBC_CTX dec_ctx;
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t mbuf[16 * 10];
|
||||
uint8_t cbuf[16 * 11];
|
||||
uint8_t pbuf[16 * 11];
|
||||
size_t mlen = 0;
|
||||
size_t clen = 0;
|
||||
size_t plen = 0;
|
||||
|
||||
uint8_t *in;
|
||||
uint8_t *out;
|
||||
size_t len;
|
||||
size_t lens[] = { 1,5,17,80 };
|
||||
int i;
|
||||
|
||||
rand_bytes(key, sizeof(key));
|
||||
rand_bytes(iv, sizeof(iv));
|
||||
|
||||
|
||||
|
||||
// first test
|
||||
|
||||
mlen = 16;
|
||||
rand_bytes(mbuf, mlen);
|
||||
|
||||
if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1
|
||||
|| sm4_cbc_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1
|
||||
|| sm4_cbc_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
clen += len;
|
||||
|
||||
// check ciphertext
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen);
|
||||
if (clen != plen || memcmp(cbuf, pbuf, plen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check decrypt
|
||||
if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1
|
||||
|| sm4_cbc_decrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1
|
||||
|| sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen += len;
|
||||
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
// second test
|
||||
|
||||
rand_bytes(mbuf, sizeof(mbuf));
|
||||
|
||||
if (sm4_cbc_encrypt_init(&enc_ctx, key, iv) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in = mbuf;
|
||||
out = cbuf;
|
||||
mlen = 0;
|
||||
clen = 0;
|
||||
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
|
||||
if (sm4_cbc_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in += lens[i];
|
||||
mlen += lens[i];
|
||||
out += len;
|
||||
clen += len;
|
||||
|
||||
}
|
||||
if (sm4_cbc_encrypt_finish(&enc_ctx, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
clen += len;
|
||||
|
||||
// check ciphertest
|
||||
sm4_cbc_padding_encrypt(&sm4_key, iv, mbuf, mlen, pbuf, &plen);
|
||||
if (plen != clen || memcmp(pbuf, cbuf, clen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check decrypt
|
||||
if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen = 0;
|
||||
in = cbuf;
|
||||
out = pbuf;
|
||||
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
|
||||
if (sm4_cbc_decrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in += lens[i];
|
||||
clen -= lens[i];
|
||||
out += len;
|
||||
plen += len;
|
||||
}
|
||||
if (sm4_cbc_decrypt_update(&dec_ctx, in, clen, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
out += len;
|
||||
plen += len;
|
||||
if (sm4_cbc_decrypt_finish(&dec_ctx, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen += len;
|
||||
|
||||
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* NOTE:
|
||||
* There is an compiler bug on Tencent Cloud/Windows Server 2022/Visual Studio 2022 and GitHub CI Windows env.
|
||||
* When calling memcpy(ctr, iv, sizeof(iv)) multiple times. The compiler might omit the memcpy()
|
||||
* As `ctr` has been changed by sm4_ctr_encrypt() and the reset to `iv` is not working, the test will fail.
|
||||
*/
|
||||
static int test_sm4_ctr_update_once(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
SM4_CTR_CTX enc_ctx;
|
||||
SM4_CTR_CTX dec_ctx;
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t ctr[16];
|
||||
uint8_t mbuf[16];
|
||||
uint8_t cbuf[16];
|
||||
uint8_t pbuf[32];
|
||||
size_t mlen = 0;
|
||||
size_t clen = 0;
|
||||
size_t plen = 0;
|
||||
size_t len;
|
||||
|
||||
rand_bytes(key, sizeof(key));
|
||||
rand_bytes(iv, sizeof(iv));
|
||||
|
||||
mlen = sizeof(mbuf);
|
||||
rand_bytes(mbuf, mlen);
|
||||
|
||||
if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1
|
||||
|| sm4_ctr_encrypt_update(&enc_ctx, mbuf, mlen, cbuf, &clen) != 1
|
||||
|| sm4_ctr_encrypt_finish(&enc_ctx, cbuf + clen, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
clen += len;
|
||||
|
||||
// check ciphertext
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
memcpy(ctr, iv, sizeof(iv)); // ctr is a variable
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf); // NOTE: sm4_ctr_encrypt() change ctr value
|
||||
|
||||
if (memcmp(cbuf, pbuf, clen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check decrypt
|
||||
if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1
|
||||
|| sm4_ctr_encrypt_update(&dec_ctx, cbuf, clen, pbuf, &plen) != 1
|
||||
|| sm4_ctr_encrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen += len;
|
||||
|
||||
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int test_sm4_ctr_update_multi_times(void)
|
||||
{
|
||||
SM4_KEY sm4_key;
|
||||
SM4_CTR_CTX enc_ctx;
|
||||
SM4_CTR_CTX dec_ctx;
|
||||
|
||||
uint8_t key[16];
|
||||
uint8_t iv[16];
|
||||
uint8_t ctr[16];
|
||||
uint8_t mbuf[16 * 10];
|
||||
uint8_t cbuf[16 * 11];
|
||||
uint8_t pbuf[16 * 11];
|
||||
size_t mlen = 0;
|
||||
size_t clen = 0;
|
||||
size_t plen = 0;
|
||||
|
||||
uint8_t *in;
|
||||
uint8_t *out;
|
||||
size_t len;
|
||||
size_t lens[] = { 1,5,17,80 };
|
||||
|
||||
int i;
|
||||
|
||||
rand_bytes(key, sizeof(key));
|
||||
rand_bytes(iv, sizeof(iv));
|
||||
|
||||
rand_bytes(mbuf, sizeof(mbuf));
|
||||
|
||||
if (sm4_ctr_encrypt_init(&enc_ctx, key, iv) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in = mbuf;
|
||||
out = cbuf;
|
||||
mlen = 0;
|
||||
clen = 0;
|
||||
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
|
||||
if (sm4_ctr_encrypt_update(&enc_ctx, in, lens[i], out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in += lens[i];
|
||||
mlen += lens[i];
|
||||
assert(mlen <= sizeof(mbuf));
|
||||
out += len;
|
||||
clen += len;
|
||||
}
|
||||
if (sm4_ctr_encrypt_finish(&enc_ctx, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
clen += len;
|
||||
|
||||
// check ciphertest
|
||||
sm4_set_encrypt_key(&sm4_key, key);
|
||||
memcpy(ctr, iv, sizeof(iv));
|
||||
sm4_ctr_encrypt(&sm4_key, ctr, mbuf, mlen, pbuf);
|
||||
if (memcmp(pbuf, cbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
// check decrypt
|
||||
if (sm4_ctr_encrypt_init(&dec_ctx, key, iv) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen = 0;
|
||||
in = cbuf;
|
||||
out = pbuf;
|
||||
for (i = 0; i < sizeof(lens)/sizeof(lens[0]); i++) {
|
||||
if (sm4_ctr_encrypt_update(&dec_ctx, in, lens[i], out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
in += lens[i];
|
||||
clen -= lens[i];
|
||||
out += len;
|
||||
plen += len;
|
||||
}
|
||||
if (sm4_ctr_encrypt_update(&dec_ctx, in, clen, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
out += len;
|
||||
plen += len;
|
||||
if (sm4_ctr_encrypt_finish(&dec_ctx, out, &len) != 1) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
plen += len;
|
||||
|
||||
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
printf("%s() ok\n", __FUNCTION__);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
|
||||
if (test_sm4() != 1) goto err;
|
||||
/*
|
||||
if (test_sm4_cbc() != 1) goto err;
|
||||
if (test_sm4_cbc_padding() != 1) goto err;
|
||||
if (test_sm4_ctr() != 1) goto err;
|
||||
|
||||
if (test_sm4_gcm() != 1) goto err;
|
||||
if (test_sm4_gcm_gbt36624_1() != 1) goto err;
|
||||
if (test_sm4_gcm_gbt36624_2() != 1) goto err;
|
||||
if (test_sm4_cbc_update() != 1) goto err;
|
||||
if (test_sm4_ctr_update_once() != 1) goto err;
|
||||
if (test_sm4_ctr_update_multi_times() != 1) goto err;
|
||||
|
||||
|
||||
*/
|
||||
printf("%s all tests passed\n", __FILE__);
|
||||
return 0;
|
||||
err:
|
||||
|
||||
Reference in New Issue
Block a user