diff --git a/CMakeLists.txt b/CMakeLists.txt
index 077439591..35d576d51 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -131,6 +131,8 @@ set(tools
 
 set(tests
 	sm4
+	sm4_cbc
+	sm4_ctr
 	sm3
 	sm4_sm3_hmac
 	sm2_z256
diff --git a/include/gmssl/ec.h b/include/gmssl/ec.h
index 2dc1c00bb..000487929 100644
--- a/include/gmssl/ec.h
+++ b/include/gmssl/ec.h
@@ -16,6 +16,7 @@
 #include <string.h>
 #include <stdint.h>
 #include <stdlib.h>
+#include <gmssl/api.h>
 #include <gmssl/sm2.h>
 #include <gmssl/oid.h>
 #include <gmssl/asn1.h>
@@ -56,7 +57,7 @@ enum {
 	EC_private_key_version = 1,
 };
 
-int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
+_gmssl_export int ec_private_key_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *d, size_t dlen);
 
 #ifdef __cplusplus
 }
diff --git a/include/gmssl/sm4.h b/include/gmssl/sm4.h
index 5b38f1441..08224bec3 100644
--- a/include/gmssl/sm4.h
+++ b/include/gmssl/sm4.h
@@ -175,8 +175,13 @@ _gmssl_export int sm4_ofb_encrypt_finish(SM4_OFB_CTX *ctx, uint8_t *out, size_t
 
 
 #ifdef ENABLE_SM4_CFB
-#define SM4_CFB_MIN_SBYTES 1
-#define SM4_CFB_MAX_SBYTES 16
+#define SM4_CFB_MIN_SBYTES 	1
+#define SM4_CFB_MAX_SBYTES	16
+
+// pre-defined values for `sbytes`
+#define SM4_CFB_8		1
+#define SM4_CFB_64		8
+#define SM4_CFB_128		16
 
 // always call `sm4_set_encrypt_key` before encrypt/decrypt
 // `sm4_cfb_encrypt/decrypt` will change the param `iv`
diff --git a/include/gmssl/sm9.h b/include/gmssl/sm9.h
index 4908e376b..26eca7404 100644
--- a/include/gmssl/sm9.h
+++ b/include/gmssl/sm9.h
@@ -75,35 +75,35 @@ typedef struct {
 	SM9_Z256_POINT ds;
 } SM9_SIGN_KEY;
 
-int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master);
-int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key);
+_gmssl_export int sm9_sign_master_key_generate(SM9_SIGN_MASTER_KEY *master);
+_gmssl_export int sm9_sign_master_key_extract_key(SM9_SIGN_MASTER_KEY *master, const char *id, size_t idlen, SM9_SIGN_KEY *key);
 
 // algorthm,parameters = sm9,sm9sign
 #define SM9_SIGN_MASTER_KEY_MAX_SIZE 171
 int sm9_sign_master_key_to_der(const SM9_SIGN_MASTER_KEY *msk, uint8_t **out, size_t *outlen);
 int sm9_sign_master_key_from_der(SM9_SIGN_MASTER_KEY *msk, const uint8_t **in, size_t *inlen);
-int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen);
-int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen);
-int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp);
-int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp);
-int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk);
+_gmssl_export int sm9_sign_master_key_info_encrypt_to_der(const SM9_SIGN_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen);
+_gmssl_export int sm9_sign_master_key_info_decrypt_from_der(SM9_SIGN_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen);
+_gmssl_export int sm9_sign_master_key_info_encrypt_to_pem(const SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp);
+_gmssl_export int sm9_sign_master_key_info_decrypt_from_pem(SM9_SIGN_MASTER_KEY *msk, const char *pass, FILE *fp);
+_gmssl_export int sm9_sign_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *msk);
 
 #define SM9_SIGN_MASTER_PUBLIC_KEY_SIZE 136
-int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
-int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
-int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp);
-int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp);
-int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk);
+_gmssl_export int sm9_sign_master_public_key_to_der(const SM9_SIGN_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
+_gmssl_export int sm9_sign_master_public_key_from_der(SM9_SIGN_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
+_gmssl_export int sm9_sign_master_public_key_to_pem(const SM9_SIGN_MASTER_KEY *mpk, FILE *fp);
+_gmssl_export int sm9_sign_master_public_key_from_pem(SM9_SIGN_MASTER_KEY *mpk, FILE *fp);
+_gmssl_export int sm9_sign_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_MASTER_KEY *mpk);
 
 // algorithm,parameters = sm9sign,<null>
 #define SM9_SIGN_KEY_SIZE 204
 int sm9_sign_key_to_der(const SM9_SIGN_KEY *key, uint8_t **out, size_t *outlen);
 int sm9_sign_key_from_der(SM9_SIGN_KEY *key, const uint8_t **in, size_t *inlen);
-int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen);
-int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen);
-int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp);
-int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp);
-int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key);
+_gmssl_export int sm9_sign_key_info_encrypt_to_der(const SM9_SIGN_KEY *key, const char *pass, uint8_t **out, size_t *outlen);
+_gmssl_export int sm9_sign_key_info_decrypt_from_der(SM9_SIGN_KEY *key, const char *pass, const uint8_t **in, size_t *inlen);
+_gmssl_export int sm9_sign_key_info_encrypt_to_pem(const SM9_SIGN_KEY *key, const char *pass, FILE *fp);
+_gmssl_export int sm9_sign_key_info_decrypt_from_pem(SM9_SIGN_KEY *key, const char *pass, FILE *fp);
+_gmssl_export int sm9_sign_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_SIGN_KEY *key);
 
 /*
 from GM/T 0080-2020 SM9 Cryptographic Alagorithm Application Specification
@@ -122,18 +122,18 @@ int sm9_do_verify(const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen,
 #define SM9_SIGNATURE_SIZE 104
 int sm9_signature_to_der(const SM9_SIGNATURE *sig, uint8_t **out, size_t *outlen);
 int sm9_signature_from_der(SM9_SIGNATURE *sig, const uint8_t **in, size_t *inlen);
-int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
+_gmssl_export int sm9_signature_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *sig, size_t siglen);
 
 typedef struct {
 	SM3_CTX sm3_ctx;
 } SM9_SIGN_CTX;
 
-int sm9_sign_init(SM9_SIGN_CTX *ctx);
-int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
-int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen);
-int sm9_verify_init(SM9_SIGN_CTX *ctx);
-int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
-int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen,
+_gmssl_export int sm9_sign_init(SM9_SIGN_CTX *ctx);
+_gmssl_export int sm9_sign_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
+_gmssl_export int sm9_sign_finish(SM9_SIGN_CTX *ctx, const SM9_SIGN_KEY *key, uint8_t *sig, size_t *siglen);
+_gmssl_export int sm9_verify_init(SM9_SIGN_CTX *ctx);
+_gmssl_export int sm9_verify_update(SM9_SIGN_CTX *ctx, const uint8_t *data, size_t datalen);
+_gmssl_export int sm9_verify_finish(SM9_SIGN_CTX *ctx, const uint8_t *sig, size_t siglen,
 	const SM9_SIGN_MASTER_KEY *mpk, const char *id, size_t idlen);
 
 
@@ -161,35 +161,35 @@ typedef struct {
 	SM9_Z256_TWIST_POINT de;
 } SM9_ENC_KEY;
 
-int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master);
-int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key);
+_gmssl_export int sm9_enc_master_key_generate(SM9_ENC_MASTER_KEY *master);
+_gmssl_export int sm9_enc_master_key_extract_key(SM9_ENC_MASTER_KEY *master, const char *id, size_t idlen, SM9_ENC_KEY *key);
 
 // algorithm,parameters = sm9,sm9encrypt
 #define SM9_ENC_MASTER_KEY_MAX_SIZE 105
 int sm9_enc_master_key_to_der(const SM9_ENC_MASTER_KEY *msk, uint8_t **out, size_t *outlen);
 int sm9_enc_master_key_from_der(SM9_ENC_MASTER_KEY *msk, const uint8_t **in, size_t *inlen);
-int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen);
-int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen);
-int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp);
-int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp);
-int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk);
+_gmssl_export int sm9_enc_master_key_info_encrypt_to_der(const SM9_ENC_MASTER_KEY *msk, const char *pass, uint8_t **out, size_t *outlen);
+_gmssl_export int sm9_enc_master_key_info_decrypt_from_der(SM9_ENC_MASTER_KEY *msk, const char *pass, const uint8_t **in, size_t *inlen);
+_gmssl_export int sm9_enc_master_key_info_encrypt_to_pem(const SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp);
+_gmssl_export int sm9_enc_master_key_info_decrypt_from_pem(SM9_ENC_MASTER_KEY *msk, const char *pass, FILE *fp);
+_gmssl_export int sm9_enc_master_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *msk);
 
 #define SM9_ENC_MASTER_PUBLIC_KEY_SIZE 70
-int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
-int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
-int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp);
-int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp);
-int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk);
+_gmssl_export int sm9_enc_master_public_key_to_der(const SM9_ENC_MASTER_KEY *mpk, uint8_t **out, size_t *outlen);
+_gmssl_export int sm9_enc_master_public_key_from_der(SM9_ENC_MASTER_KEY *mpk, const uint8_t **in, size_t *inlen);
+_gmssl_export int sm9_enc_master_public_key_to_pem(const SM9_ENC_MASTER_KEY *mpk, FILE *fp);
+_gmssl_export int sm9_enc_master_public_key_from_pem(SM9_ENC_MASTER_KEY *mpk, FILE *fp);
+_gmssl_export int sm9_enc_master_public_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_MASTER_KEY *mpk);
 
 // algorithm,parameters = sm9encrypt,<null>
 #define SM9_ENC_KEY_SIZE 204
 int sm9_enc_key_to_der(const SM9_ENC_KEY *key, uint8_t **out, size_t *outlen);
 int sm9_enc_key_from_der(SM9_ENC_KEY *key, const uint8_t **in, size_t *inlen);
-int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen);
-int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen);
-int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp);
-int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp);
-int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key);
+_gmssl_export int sm9_enc_key_info_encrypt_to_der(const SM9_ENC_KEY *key, const char *pass, uint8_t **out, size_t *outlen);
+_gmssl_export int sm9_enc_key_info_decrypt_from_der(SM9_ENC_KEY *key, const char *pass, const uint8_t **in, size_t *inlen);
+_gmssl_export int sm9_enc_key_info_encrypt_to_pem(const SM9_ENC_KEY *key, const char *pass, FILE *fp);
+_gmssl_export int sm9_enc_key_info_decrypt_from_pem(SM9_ENC_KEY *key, const char *pass, FILE *fp);
+_gmssl_export int sm9_enc_key_print(FILE *fp, int fmt, int ind, const char *label, const SM9_ENC_KEY *key);
 
 #define SM9_MAX_PRIVATE_KEY_SIZE (SM9_SIGN_KEY_SIZE) // MAX(SIGN_MASTER_KEY, SIGN_KEY, ENC_MASTER_KEY, ENC_KEY)
 #define SM9_MAX_PRIVATE_KEY_INFO_SIZE 512
@@ -217,10 +217,10 @@ int sm9_ciphertext_to_der(const SM9_Z256_POINT *C1, const uint8_t *c2, size_t c2
 	const uint8_t c3[SM3_HMAC_SIZE], uint8_t **out, size_t *outlen);
 int sm9_ciphertext_from_der(SM9_Z256_POINT *C1, const uint8_t **c2, size_t *c2len,
 	const uint8_t **c3, const uint8_t **in, size_t *inlen);
-int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
-int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen,
+_gmssl_export int sm9_ciphertext_print(FILE *fp, int fmt, int ind, const char *label, const uint8_t *a, size_t alen);
+_gmssl_export int sm9_encrypt(const SM9_ENC_MASTER_KEY *mpk, const char *id, size_t idlen,
 	const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
-int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen,
+_gmssl_export int sm9_decrypt(const SM9_ENC_KEY *key, const char *id, size_t idlen,
 	const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen);
 
 
diff --git a/src/sm2_key.c b/src/sm2_key.c
index 730d0e9be..3fd93ab12 100644
--- a/src/sm2_key.c
+++ b/src/sm2_key.c
@@ -356,7 +356,6 @@ int sm2_private_key_info_print(FILE *fp, int fmt, int ind, const char *label, co
 	return -1;
 }
 
-#ifdef ENABLE_SM2_PRIVATE_KEY_EXPORT
 int sm2_private_key_info_to_pem(const SM2_KEY *key, FILE *fp)
 {
 	int ret = -1;
@@ -405,7 +404,6 @@ int sm2_private_key_info_from_pem(SM2_KEY *sm2_key, FILE *fp)
 	}
 	return 1;
 }
-#endif
 
 int sm2_public_key_info_to_der(const SM2_KEY *pub_key, uint8_t **out, size_t *outlen)
 {
@@ -440,8 +438,6 @@ int sm2_public_key_info_from_der(SM2_KEY *pub_key, const uint8_t **in, size_t *i
 	return 1;
 }
 
-#ifdef ENABLE_SM2_PRIVATE_KEY_EXPORT
-
 // FIXME: side-channel of Base64
 int sm2_private_key_to_pem(const SM2_KEY *a, FILE *fp)
 {
@@ -477,7 +473,6 @@ int sm2_private_key_from_pem(SM2_KEY *a, FILE *fp)
 	}
 	return 1;
 }
-#endif
 
 int sm2_public_key_info_to_pem(const SM2_KEY *a, FILE *fp)
 {
diff --git a/src/sm4_xts.c b/src/sm4_xts.c
index 7795bfe1c..12e805b19 100644
--- a/src/sm4_xts.c
+++ b/src/sm4_xts.c
@@ -92,7 +92,7 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea
 
 	for (i = 0; i < nblocks - 2; i++) {
 		gmssl_memxor(block, in, T, 16);
-		sm4_decrypt(key1, block, block);
+		sm4_encrypt(key1, block, block);
 		gmssl_memxor(out, block, T, 16);
 
 		gf128_from_bytes(a, T);
@@ -106,7 +106,7 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea
 
 	if (inlen % 16 == 0) {
 		gmssl_memxor(block, in, T, 16);
-		sm4_decrypt(key1, block, block);
+		sm4_encrypt(key1, block, block);
 		gmssl_memxor(out, block, T, 16);
 
 	} else  {
@@ -117,7 +117,7 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea
 		gf128_to_bytes(a, T1);
 
 		gmssl_memxor(block, in, T1, 16);
-		sm4_decrypt(key1, block, block);
+		sm4_encrypt(key1, block, block);
 		gmssl_memxor(block, block, T1, 16);
 
 		in += 16;
@@ -127,7 +127,7 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea
 		memcpy(block, in, inlen);
 
 		gmssl_memxor(block, block, T, 16);
-		sm4_decrypt(key1, block, block);
+		sm4_encrypt(key1, block, block);
 		gmssl_memxor(out, block, T, 16);
 	}
 
diff --git a/tests/rdrandtest.c b/tests/rdrandtest.c
new file mode 100644
index 000000000..b57e76e9e
--- /dev/null
+++ b/tests/rdrandtest.c
@@ -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;
+}
diff --git a/tests/sm4_cbctest.c b/tests/sm4_cbctest.c
new file mode 100644
index 000000000..bbacf921c
--- /dev/null
+++ b/tests/sm4_cbctest.c
@@ -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;
+}
diff --git a/tests/sm4_ccmtest.c b/tests/sm4_ccmtest.c
index ce66f2274..fefddce22 100644
--- a/tests/sm4_ccmtest.c
+++ b/tests/sm4_ccmtest.c
@@ -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:
diff --git a/tests/sm4_cfbtest.c b/tests/sm4_cfbtest.c
index 8e031e375..26980d474 100644
--- a/tests/sm4_cfbtest.c
+++ b/tests/sm4_cfbtest.c
@@ -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;
diff --git a/tests/sm4_ctrtest.c b/tests/sm4_ctrtest.c
new file mode 100644
index 000000000..73b4bfc1e
--- /dev/null
+++ b/tests/sm4_ctrtest.c
@@ -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;
+}
diff --git a/tests/sm4_ecbtest.c b/tests/sm4_ecbtest.c
index 75468d5b1..6b05308f8 100644
--- a/tests/sm4_ecbtest.c
+++ b/tests/sm4_ecbtest.c
@@ -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;
diff --git a/tests/sm4_gcmtest.c b/tests/sm4_gcmtest.c
index 429d682bb..4d7bee7b1 100644
--- a/tests/sm4_gcmtest.c
+++ b/tests/sm4_gcmtest.c
@@ -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:
diff --git a/tests/sm4_ofbtest.c b/tests/sm4_ofbtest.c
index 8698d8998..2d673ec69 100644
--- a/tests/sm4_ofbtest.c
+++ b/tests/sm4_ofbtest.c
@@ -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;
diff --git a/tests/sm4_xtstest.c b/tests/sm4_xtstest.c
index 378e19b8d..4fe8b88b0 100644
--- a/tests/sm4_xtstest.c
+++ b/tests/sm4_xtstest.c
@@ -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:
diff --git a/tests/sm4test.c b/tests/sm4test.c
index fb455d115..b3d1065eb 100644
--- a/tests/sm4test.c
+++ b/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: