Fix SM4 API bugs and change behavior

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

View File

@@ -768,7 +768,7 @@ endif()
# #
set(CPACK_PACKAGE_NAME "GmSSL") set(CPACK_PACKAGE_NAME "GmSSL")
set(CPACK_PACKAGE_VENDOR "GmSSL develop team") set(CPACK_PACKAGE_VENDOR "GmSSL develop team")
set(CPACK_PACKAGE_VERSION "3.2.0-dev.1034") set(CPACK_PACKAGE_VERSION "3.2.0-dev.1035")
set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md) set(CPACK_PACKAGE_DESCRIPTION_FILE ${PROJECT_SOURCE_DIR}/README.md)
set(CPACK_NSIS_MODIFY_PATH ON) set(CPACK_NSIS_MODIFY_PATH ON)
include(CPack) include(CPack)

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -26,9 +26,9 @@ typedef struct {
#define SM4_CBC_MAC_SIZE (SM4_BLOCK_SIZE) #define SM4_CBC_MAC_SIZE (SM4_BLOCK_SIZE)
void sm4_cbc_mac_init(SM4_CBC_MAC_CTX *ctx, const uint8_t key[16]); int sm4_cbc_mac_init(SM4_CBC_MAC_CTX *ctx, const uint8_t key[16]);
void sm4_cbc_mac_update(SM4_CBC_MAC_CTX *ctx, const uint8_t *data, size_t datalen); int sm4_cbc_mac_update(SM4_CBC_MAC_CTX *ctx, const uint8_t *data, size_t datalen);
void sm4_cbc_mac_finish(SM4_CBC_MAC_CTX *ctx, uint8_t mac[16]); int sm4_cbc_mac_finish(SM4_CBC_MAC_CTX *ctx, uint8_t mac[16]);
#ifdef __cplusplus #ifdef __cplusplus

View File

@@ -19,7 +19,7 @@ extern "C" {
// Also update CPACK_PACKAGE_VERSION in CMakeLists.txt // Also update CPACK_PACKAGE_VERSION in CMakeLists.txt
#define GMSSL_VERSION_NUM 30200 #define GMSSL_VERSION_NUM 30200
#define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1034" #define GMSSL_VERSION_STR "GmSSL 3.2.0-dev.1035"
int gmssl_version_num(void); int gmssl_version_num(void);
const char *gmssl_version_str(void); const char *gmssl_version_str(void);

View File

@@ -22,6 +22,11 @@ int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t piv[16],
size_t rem = inlen % 16; size_t rem = inlen % 16;
int padding = 16 - inlen % 16; int padding = 16 - inlen % 16;
if (!key || !piv || (!in && inlen) || !out || !outlen) {
error_print();
return -1;
}
memcpy(iv, piv, 16); memcpy(iv, piv, 16);
if (in) { if (in) {
@@ -35,6 +40,9 @@ int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t piv[16],
} }
sm4_cbc_encrypt_blocks(key, iv, block, 1, out); sm4_cbc_encrypt_blocks(key, iv, block, 1, out);
*outlen = inlen - rem + 16; *outlen = inlen - rem + 16;
gmssl_secure_clear(iv, sizeof(iv));
gmssl_secure_clear(block, sizeof(block));
return 1; return 1;
} }
@@ -48,37 +56,47 @@ int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t piv[16],
int padding; int padding;
int i; int i;
memcpy(iv, piv, 16); if (!key || !piv || !in || !inlen || !out || !outlen) {
error_print();
if (inlen == 0) {
error_puts("warning: input lenght = 0");
return 0;
}
if (inlen%16 != 0 || inlen < 16) {
error_puts("invalid cbc ciphertext length");
return -1; return -1;
} }
if (inlen > 16) { if (inlen % 16 != 0 || inlen < 16) {
sm4_cbc_decrypt_blocks(key, iv, in, inlen/16 - 1, out); error_print();
return -1;
} }
if (inlen/16 > 1)
memcpy(iv, in + inlen - 32, 16);
else memcpy(iv, piv, 16);
sm4_cbc_decrypt_blocks(key, iv, in + inlen - 16, 1, block); sm4_cbc_decrypt_blocks(key, iv, in + inlen - 16, 1, block);
gmssl_secure_clear(iv, sizeof(iv));
padding = block[15]; padding = block[15];
if (padding < 1 || padding > 16) { if (padding < 1 || padding > 16) {
gmssl_secure_clear(block, sizeof(block));
error_print(); error_print();
return -1; return -1;
} }
for (i = 16 - padding; i < 16; i++) { for (i = 16 - padding; i < 16; i++) {
if (block[i] != padding) { if (block[i] != padding) {
gmssl_secure_clear(block, sizeof(block));
error_print(); error_print();
return -1; return -1;
} }
} }
if (inlen/16 > 1) {
memcpy(iv, piv, 16);
sm4_cbc_decrypt_blocks(key, iv, in, inlen/16 - 1, out);
gmssl_secure_clear(iv, sizeof(iv));
}
len -= padding; len -= padding;
memcpy(out + inlen - 16, block, len); memcpy(out + inlen - 16, block, len);
*outlen = inlen - padding; *outlen = inlen - padding;
gmssl_secure_clear(block, sizeof(block));
return 1; return 1;
} }
@@ -103,19 +121,19 @@ int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx,
size_t nblocks; size_t nblocks;
size_t len; size_t len;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
left = SM4_BLOCK_SIZE - ctx->block_nbytes; left = SM4_BLOCK_SIZE - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
@@ -147,14 +165,10 @@ int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx,
int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_cbc_encrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE;
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
@@ -183,22 +197,23 @@ int sm4_cbc_decrypt_init(SM4_CBC_CTX *ctx,
int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx, int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{ {
size_t left, len, nblocks; size_t left;
size_t len;
size_t nblocks;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->block_nbytes > SM4_BLOCK_SIZE) { if (ctx->block_nbytes > SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
left = SM4_BLOCK_SIZE - ctx->block_nbytes; left = SM4_BLOCK_SIZE - ctx->block_nbytes;
if (inlen <= left) { if (inlen <= left) {
@@ -228,14 +243,10 @@ int sm4_cbc_decrypt_update(SM4_CBC_CTX *ctx,
int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_cbc_decrypt_finish(SM4_CBC_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE;
return 1;
}
if (ctx->block_nbytes != SM4_BLOCK_SIZE) { if (ctx->block_nbytes != SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -17,15 +17,31 @@
#include <gmssl/sm4_cbc_mac.h> #include <gmssl/sm4_cbc_mac.h>
void sm4_cbc_mac_init(SM4_CBC_MAC_CTX *ctx, const uint8_t key[16]) int sm4_cbc_mac_init(SM4_CBC_MAC_CTX *ctx, const uint8_t key[16])
{ {
if (!ctx || !key) {
error_print();
return -1;
}
sm4_set_encrypt_key(&ctx->key, key); sm4_set_encrypt_key(&ctx->key, key);
memset(ctx->iv, 0, 16); memset(ctx->iv, 0, 16);
ctx->ivlen = 0; ctx->ivlen = 0;
return 1;
} }
void sm4_cbc_mac_update(SM4_CBC_MAC_CTX *ctx, const uint8_t *data, size_t datalen) int sm4_cbc_mac_update(SM4_CBC_MAC_CTX *ctx, const uint8_t *data, size_t datalen)
{ {
if (!ctx || (!data && datalen)) {
error_print();
return -1;
}
if (ctx->ivlen >= 16) {
error_print();
return -1;
}
if (!data || !datalen) {
return 1;
}
while (datalen) { while (datalen) {
size_t ivleft = 16 - ctx->ivlen; size_t ivleft = 16 - ctx->ivlen;
size_t len = datalen < ivleft ? datalen : ivleft; size_t len = datalen < ivleft ? datalen : ivleft;
@@ -38,12 +54,23 @@ void sm4_cbc_mac_update(SM4_CBC_MAC_CTX *ctx, const uint8_t *data, size_t datale
data += len; data += len;
datalen -= len; datalen -= len;
} }
return 1;
} }
void sm4_cbc_mac_finish(SM4_CBC_MAC_CTX *ctx, uint8_t mac[16]) int sm4_cbc_mac_finish(SM4_CBC_MAC_CTX *ctx, uint8_t mac[16])
{ {
if (!ctx || !mac) {
error_print();
return -1;
}
if (ctx->ivlen >= 16) {
error_print();
return -1;
}
if (ctx->ivlen) { if (ctx->ivlen) {
sm4_encrypt(&ctx->key, ctx->iv, ctx->iv); sm4_encrypt(&ctx->key, ctx->iv, ctx->iv);
ctx->ivlen = 0;
} }
memcpy(mac, ctx->iv, 16); memcpy(mac, ctx->iv, 16);
return 1;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -38,10 +38,14 @@ int sm4_cbc_sm3_hmac_encrypt_init(SM4_CBC_SM3_HMAC_CTX *ctx,
int sm4_cbc_sm3_hmac_encrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) int sm4_cbc_sm3_hmac_encrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !in || !out || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0;
if (!in || !inlen) {
return 1;
}
if (sm4_cbc_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) { if (sm4_cbc_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) {
error_print(); error_print();
return -1; return -1;
@@ -90,7 +94,7 @@ int sm4_cbc_sm3_hmac_decrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx, const uint8_t *in
{ {
size_t len; size_t len;
if (!ctx || !in || !out || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
@@ -99,6 +103,10 @@ int sm4_cbc_sm3_hmac_decrypt_update(SM4_CBC_SM3_HMAC_CTX *ctx, const uint8_t *in
return -1; return -1;
} }
*outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->maclen < SM3_HMAC_SIZE) { if (ctx->maclen < SM3_HMAC_SIZE) {
len = SM3_HMAC_SIZE - ctx->maclen; len = SM3_HMAC_SIZE - ctx->maclen;
if (inlen <= len) { if (inlen <= len) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -8,10 +8,10 @@
*/ */
#include <gmssl/sm4.h>
#include <gmssl/mem.h> #include <gmssl/mem.h>
#include <gmssl/sm4_cbc_mac.h>
#include <gmssl/error.h> #include <gmssl/error.h>
#include <gmssl/sm4.h>
#include <gmssl/sm4_cbc_mac.h>
static void length_to_bytes(size_t len, size_t nbytes, uint8_t *out) static void length_to_bytes(size_t len, size_t nbytes, uint8_t *out)
@@ -60,11 +60,11 @@ int sm4_ccm_encrypt(const SM4_KEY *sm4_key, const uint8_t *iv, size_t ivlen,
uint8_t mac[16]; uint8_t mac[16];
size_t inlen_size; size_t inlen_size;
if (ivlen < 7 || ivlen > 13) { if (!sm4_key || !iv || (!aad && aadlen) || (!in && inlen) || !out || !tag) {
error_print(); error_print();
return -1; return -1;
} }
if (!aad && aadlen) { if (ivlen < 7 || ivlen > 13) {
error_print(); error_print();
return -1; return -1;
} }
@@ -109,7 +109,7 @@ int sm4_ccm_encrypt(const SM4_KEY *sm4_key, const uint8_t *iv, size_t ivlen,
} }
sm4_cbc_mac_update(&mac_ctx, block, alen); sm4_cbc_mac_update(&mac_ctx, block, alen);
sm4_cbc_mac_update(&mac_ctx, aad, aadlen); sm4_cbc_mac_update(&mac_ctx, aad, aadlen);
if (alen + aadlen % 16) { if ((alen + aadlen) % 16) {
sm4_cbc_mac_update(&mac_ctx, zeros, 16 - (alen + aadlen)%16); sm4_cbc_mac_update(&mac_ctx, zeros, 16 - (alen + aadlen)%16);
} }
} }
@@ -145,11 +145,11 @@ int sm4_ccm_decrypt(const SM4_KEY *sm4_key, const uint8_t *iv, size_t ivlen,
uint8_t mac[16]; uint8_t mac[16];
size_t inlen_size; size_t inlen_size;
if (ivlen < 7 || ivlen > 13) { if (!sm4_key || !iv || (!aad && aadlen) || (!in && inlen) || !tag || !out) {
error_print(); error_print();
return -1; return -1;
} }
if (!aad && aadlen) { if (ivlen < 7 || ivlen > 13) {
error_print(); error_print();
return -1; return -1;
} }
@@ -194,7 +194,7 @@ int sm4_ccm_decrypt(const SM4_KEY *sm4_key, const uint8_t *iv, size_t ivlen,
} }
sm4_cbc_mac_update(&mac_ctx, block, alen); sm4_cbc_mac_update(&mac_ctx, block, alen);
sm4_cbc_mac_update(&mac_ctx, aad, aadlen); sm4_cbc_mac_update(&mac_ctx, aad, aadlen);
if (alen + aadlen % 16) { if ((alen + aadlen) % 16) {
sm4_cbc_mac_update(&mac_ctx, zeros, 16 - (alen + aadlen)%16); sm4_cbc_mac_update(&mac_ctx, zeros, 16 - (alen + aadlen)%16);
} }
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -91,19 +91,19 @@ int sm4_cfb_encrypt_update(SM4_CFB_CTX *ctx,
size_t nblocks; size_t nblocks;
size_t len; size_t len;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->block_nbytes >= ctx->sbytes) { if (ctx->block_nbytes >= ctx->sbytes) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
left = ctx->sbytes - ctx->block_nbytes; left = ctx->sbytes - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
@@ -135,19 +135,17 @@ int sm4_cfb_encrypt_update(SM4_CFB_CTX *ctx,
int sm4_cfb_encrypt_finish(SM4_CFB_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_cfb_encrypt_finish(SM4_CFB_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE;
return 1;
}
if (ctx->block_nbytes >= ctx->sbytes) { if (ctx->block_nbytes >= ctx->sbytes) {
error_print(); error_print();
return -1; return -1;
} }
if (ctx->block_nbytes) {
sm4_cfb_encrypt(&ctx->sm4_key, ctx->sbytes, ctx->iv, ctx->block, ctx->block_nbytes, out); sm4_cfb_encrypt(&ctx->sm4_key, ctx->sbytes, ctx->iv, ctx->block, ctx->block_nbytes, out);
}
*outlen = ctx->block_nbytes; *outlen = ctx->block_nbytes;
return 1; return 1;
} }
@@ -178,22 +176,20 @@ int sm4_cfb_decrypt_update(SM4_CFB_CTX *ctx,
size_t nblocks; size_t nblocks;
size_t len; size_t len;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->block_nbytes >= ctx->sbytes) { if (ctx->block_nbytes >= ctx->sbytes) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0;
if (ctx->block_nbytes) {
error_print();
*outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) {
left = ctx->sbytes - ctx->block_nbytes; left = ctx->sbytes - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
memcpy(ctx->block + ctx->block_nbytes, in, inlen); memcpy(ctx->block + ctx->block_nbytes, in, inlen);
@@ -224,19 +220,17 @@ int sm4_cfb_decrypt_update(SM4_CFB_CTX *ctx,
int sm4_cfb_decrypt_finish(SM4_CFB_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_cfb_decrypt_finish(SM4_CFB_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE;
return 1;
}
if (ctx->block_nbytes >= ctx->sbytes) { if (ctx->block_nbytes >= ctx->sbytes) {
error_print(); error_print();
return -1; return -1;
} }
if (ctx->block_nbytes) {
sm4_cfb_decrypt(&ctx->sm4_key, ctx->sbytes, ctx->iv, ctx->block, ctx->block_nbytes, out); sm4_cfb_decrypt(&ctx->sm4_key, ctx->sbytes, ctx->iv, ctx->block, ctx->block_nbytes, out);
}
*outlen = ctx->block_nbytes; *outlen = ctx->block_nbytes;
return 1; return 1;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -70,19 +70,19 @@ int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx,
size_t nblocks; size_t nblocks;
size_t len; size_t len;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
left = SM4_BLOCK_SIZE - ctx->block_nbytes; left = SM4_BLOCK_SIZE - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
@@ -114,20 +114,19 @@ int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx,
int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_ctr_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE;
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
if (ctx->block_nbytes) {
sm4_ctr_encrypt_blocks(&ctx->sm4_key, ctx->ctr, ctx->block, 1, ctx->block); sm4_ctr_encrypt_blocks(&ctx->sm4_key, ctx->ctr, ctx->block, 1, ctx->block);
memcpy(out, ctx->block, ctx->block_nbytes); memcpy(out, ctx->block, ctx->block_nbytes);
}
*outlen = ctx->block_nbytes; *outlen = ctx->block_nbytes;
return 1; return 1;
} }
@@ -153,19 +152,19 @@ int sm4_ctr32_encrypt_update(SM4_CTR_CTX *ctx,
size_t nblocks; size_t nblocks;
size_t len; size_t len;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
left = SM4_BLOCK_SIZE - ctx->block_nbytes; left = SM4_BLOCK_SIZE - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
@@ -197,20 +196,19 @@ int sm4_ctr32_encrypt_update(SM4_CTR_CTX *ctx,
int sm4_ctr32_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_ctr32_encrypt_finish(SM4_CTR_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE;
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
if (ctx->block_nbytes) {
sm4_ctr32_encrypt_blocks(&ctx->sm4_key, ctx->ctr, ctx->block, 1, ctx->block); sm4_ctr32_encrypt_blocks(&ctx->sm4_key, ctx->ctr, ctx->block, 1, ctx->block);
memcpy(out, ctx->block, ctx->block_nbytes); memcpy(out, ctx->block, ctx->block_nbytes);
}
*outlen = ctx->block_nbytes; *outlen = ctx->block_nbytes;
return 1; return 1;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -38,10 +38,14 @@ int sm4_ctr_sm3_hmac_encrypt_init(SM4_CTR_SM3_HMAC_CTX *ctx,
int sm4_ctr_sm3_hmac_encrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) int sm4_ctr_sm3_hmac_encrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !in || !out || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0;
if (!in || !inlen) {
return 1;
}
if (sm4_ctr_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) { if (sm4_ctr_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) {
error_print(); error_print();
return -1; return -1;
@@ -90,7 +94,7 @@ int sm4_ctr_sm3_hmac_decrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, const uint8_t *in
{ {
size_t len; size_t len;
if (!ctx || !in || !out || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
@@ -99,6 +103,10 @@ int sm4_ctr_sm3_hmac_decrypt_update(SM4_CTR_SM3_HMAC_CTX *ctx, const uint8_t *in
return -1; return -1;
} }
*outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->maclen < SM3_HMAC_SIZE) { if (ctx->maclen < SM3_HMAC_SIZE) {
len = SM3_HMAC_SIZE - ctx->maclen; len = SM3_HMAC_SIZE - ctx->maclen;
if (inlen <= len) { if (inlen <= len) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -32,19 +32,19 @@ int sm4_ecb_encrypt_update(SM4_ECB_CTX *ctx,
size_t nblocks; size_t nblocks;
size_t len; size_t len;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
left = SM4_BLOCK_SIZE - ctx->block_nbytes; left = SM4_BLOCK_SIZE - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
@@ -76,14 +76,10 @@ int sm4_ecb_encrypt_update(SM4_ECB_CTX *ctx,
int sm4_ecb_encrypt_finish(SM4_ECB_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_ecb_encrypt_finish(SM4_ECB_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE; // anyway, caller should prepare a block buffer to support any length input
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -34,6 +34,10 @@ int sm4_gcm_encrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
uint8_t Y[16]; uint8_t Y[16];
uint8_t T[16]; uint8_t T[16];
if (!key || !iv || (!aad && aadlen) || (!in && inlen) || !out || !tag) {
error_print();
return -1;
}
if (ivlen < SM4_GCM_MIN_IV_SIZE || ivlen > SM4_GCM_MAX_IV_SIZE) { if (ivlen < SM4_GCM_MIN_IV_SIZE || ivlen > SM4_GCM_MAX_IV_SIZE) {
error_print(); error_print();
return -1; return -1;
@@ -76,6 +80,10 @@ int sm4_gcm_decrypt(const SM4_KEY *key, const uint8_t *iv, size_t ivlen,
uint8_t Y[16]; uint8_t Y[16];
uint8_t T[16]; uint8_t T[16];
if (!key || !iv || (!aad && aadlen) || (!in && inlen) || !tag || !out) {
error_print();
return -1;
}
if (ivlen < SM4_GCM_MIN_IV_SIZE || ivlen > SM4_GCM_MAX_IV_SIZE) { if (ivlen < SM4_GCM_MIN_IV_SIZE || ivlen > SM4_GCM_MAX_IV_SIZE) {
error_print(); error_print();
return -1; return -1;
@@ -170,22 +178,24 @@ int sm4_gcm_encrypt_init(SM4_GCM_CTX *ctx,
int sm4_gcm_encrypt_update(SM4_GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) int sm4_gcm_encrypt_update(SM4_GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0;
if (!in || !inlen) {
return 1;
}
if (inlen > INT_MAX) { if (inlen > INT_MAX) {
error_print(); error_print();
return -1; return -1;
} }
if (inlen > SM4_GCM_MAX_PLAINTEXT_SIZE - ctx->encedlen) { if (ctx->encedlen > SM4_GCM_MAX_PLAINTEXT_SIZE
|| inlen > SM4_GCM_MAX_PLAINTEXT_SIZE - ctx->encedlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (sm4_ctr32_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) { if (sm4_ctr32_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) {
error_print(); error_print();
@@ -202,14 +212,10 @@ int sm4_gcm_encrypt_finish(SM4_GCM_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
uint8_t mac[16]; uint8_t mac[16];
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE * 2; // GCM output extra mac tag
return 1;
}
if (sm4_ctr32_encrypt_finish(&ctx->enc_ctx, out, outlen) != 1) { if (sm4_ctr32_encrypt_finish(&ctx->enc_ctx, out, outlen) != 1) {
error_print(); error_print();
return -1; return -1;
@@ -234,28 +240,36 @@ int sm4_gcm_decrypt_init(SM4_GCM_CTX *ctx,
int sm4_gcm_decrypt_update(SM4_GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) int sm4_gcm_decrypt_update(SM4_GCM_CTX *ctx, const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{ {
size_t len; size_t len;
size_t datalen = 0;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0;
if (!in || !inlen) {
return 1;
}
if (inlen > INT_MAX) { if (inlen > INT_MAX) {
error_print(); error_print();
return -1; return -1;
} }
if (inlen > SM4_GCM_MAX_PLAINTEXT_SIZE - ctx->encedlen) {
error_print();
return -1;
}
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->maclen > ctx->taglen) { if (ctx->maclen > ctx->taglen) {
error_print(); error_print();
return -1; return -1;
} }
if (ctx->encedlen > SM4_GCM_MAX_PLAINTEXT_SIZE) {
error_print();
return -1;
}
if (inlen > ctx->taglen - ctx->maclen) {
datalen = inlen - (ctx->taglen - ctx->maclen);
if (datalen > SM4_GCM_MAX_PLAINTEXT_SIZE - ctx->encedlen) {
error_print();
return -1;
}
}
if (ctx->maclen < ctx->taglen) { if (ctx->maclen < ctx->taglen) {
len = ctx->taglen - ctx->maclen; len = ctx->taglen - ctx->maclen;
@@ -300,7 +314,7 @@ int sm4_gcm_decrypt_update(SM4_GCM_CTX *ctx, const uint8_t *in, size_t inlen, ui
memcpy(ctx->mac, in + inlen, GHASH_SIZE); memcpy(ctx->mac, in + inlen, GHASH_SIZE);
} }
ctx->encedlen += inlen; ctx->encedlen += datalen;
return 1; return 1;
} }
@@ -308,14 +322,10 @@ int sm4_gcm_decrypt_finish(SM4_GCM_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
uint8_t mac[GHASH_SIZE]; uint8_t mac[GHASH_SIZE];
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE;
return 1;
}
if (ctx->maclen != ctx->taglen) { if (ctx->maclen != ctx->taglen) {
error_print(); error_print();
return -1; return -1;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -49,19 +49,19 @@ int sm4_ofb_encrypt_update(SM4_OFB_CTX *ctx,
size_t nblocks; size_t nblocks;
size_t len; size_t len;
if (!ctx || !in || !outlen) { if (!ctx || (!in && inlen) || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = 16 * ((inlen + 15)/16);
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
left = SM4_BLOCK_SIZE - ctx->block_nbytes; left = SM4_BLOCK_SIZE - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
@@ -93,20 +93,17 @@ int sm4_ofb_encrypt_update(SM4_OFB_CTX *ctx,
int sm4_ofb_encrypt_finish(SM4_OFB_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_ofb_encrypt_finish(SM4_OFB_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
if (!ctx || !outlen) { if (!ctx || !out || !outlen) {
error_print(); error_print();
return -1; return -1;
} }
if (!out) {
*outlen = SM4_BLOCK_SIZE;
return 1;
}
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) { if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
if (ctx->block_nbytes) {
sm4_ofb_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, ctx->block_nbytes, out); sm4_ofb_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, ctx->block_nbytes, out);
}
*outlen = ctx->block_nbytes; *outlen = ctx->block_nbytes;
return 1; return 1;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -22,6 +22,10 @@ int sm4_xts_encrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea
size_t nblocks, i; size_t nblocks, i;
gf128_t a; gf128_t a;
if (!key1 || !key2 || !tweak || (!in && inlen) || !out) {
error_print();
return -1;
}
if (inlen < 16) { if (inlen < 16) {
error_print(); error_print();
return -1; return -1;
@@ -83,6 +87,10 @@ int sm4_xts_decrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea
size_t nblocks, i; size_t nblocks, i;
gf128_t a; gf128_t a;
if (!key1 || !key2 || !tweak || (!in && inlen) || !out) {
error_print();
return -1;
}
if (inlen < 16) { if (inlen < 16) {
error_print(); error_print();
return -1; return -1;
@@ -149,10 +157,11 @@ static void tweak_incr(uint8_t a[16])
int sm4_xts_encrypt_init(SM4_XTS_CTX *ctx, const uint8_t key[32], const uint8_t iv[16], size_t data_unit_size) int sm4_xts_encrypt_init(SM4_XTS_CTX *ctx, const uint8_t key[32], const uint8_t iv[16], size_t data_unit_size)
{ {
if (data_unit_size < SM4_BLOCK_SIZE) { if (!ctx || !key || !iv || data_unit_size < SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
memset(ctx, 0, sizeof(*ctx));
sm4_set_encrypt_key(&ctx->key1, key); sm4_set_encrypt_key(&ctx->key1, key);
sm4_set_encrypt_key(&ctx->key2, key + 16); sm4_set_encrypt_key(&ctx->key2, key + 16);
memcpy(ctx->tweak, iv, 16); memcpy(ctx->tweak, iv, 16);
@@ -168,14 +177,26 @@ int sm4_xts_encrypt_init(SM4_XTS_CTX *ctx, const uint8_t key[32], const uint8_t
int sm4_xts_encrypt_update(SM4_XTS_CTX *ctx, int sm4_xts_encrypt_update(SM4_XTS_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{ {
size_t DATA_UNIT_SIZE = ctx->data_unit_size; size_t DATA_UNIT_SIZE;
size_t left; size_t left;
if (!ctx || (!in && inlen) || !out || !outlen) {
error_print();
return -1;
}
if (!ctx->block || ctx->data_unit_size < SM4_BLOCK_SIZE) {
error_print();
return -1;
}
DATA_UNIT_SIZE = ctx->data_unit_size;
if (ctx->block_nbytes >= DATA_UNIT_SIZE) { if (ctx->block_nbytes >= DATA_UNIT_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
left = DATA_UNIT_SIZE - ctx->block_nbytes; left = DATA_UNIT_SIZE - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
@@ -214,7 +235,16 @@ int sm4_xts_encrypt_update(SM4_XTS_CTX *ctx,
int sm4_xts_encrypt_finish(SM4_XTS_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_xts_encrypt_finish(SM4_XTS_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
size_t DATA_UNIT_SIZE = ctx->data_unit_size; size_t DATA_UNIT_SIZE;
if (!ctx || !out || !outlen) {
error_print();
return -1;
}
if (!ctx->block || ctx->data_unit_size < SM4_BLOCK_SIZE) {
error_print();
return -1;
}
DATA_UNIT_SIZE = ctx->data_unit_size;
if (ctx->block_nbytes >= DATA_UNIT_SIZE) { if (ctx->block_nbytes >= DATA_UNIT_SIZE) {
error_print(); error_print();
return -1; return -1;
@@ -234,10 +264,11 @@ int sm4_xts_encrypt_finish(SM4_XTS_CTX *ctx, uint8_t *out, size_t *outlen)
int sm4_xts_decrypt_init(SM4_XTS_CTX *ctx, const uint8_t key[32], const uint8_t iv[16], size_t data_unit_size) int sm4_xts_decrypt_init(SM4_XTS_CTX *ctx, const uint8_t key[32], const uint8_t iv[16], size_t data_unit_size)
{ {
if (data_unit_size < SM4_BLOCK_SIZE) { if (!ctx || !key || !iv || data_unit_size < SM4_BLOCK_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
memset(ctx, 0, sizeof(*ctx));
sm4_set_decrypt_key(&ctx->key1, key); sm4_set_decrypt_key(&ctx->key1, key);
sm4_set_encrypt_key(&ctx->key2, key + 16); sm4_set_encrypt_key(&ctx->key2, key + 16);
memcpy(ctx->tweak, iv, 16); memcpy(ctx->tweak, iv, 16);
@@ -253,16 +284,27 @@ int sm4_xts_decrypt_init(SM4_XTS_CTX *ctx, const uint8_t key[32], const uint8_t
int sm4_xts_decrypt_update(SM4_XTS_CTX *ctx, int sm4_xts_decrypt_update(SM4_XTS_CTX *ctx,
const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen) const uint8_t *in, size_t inlen, uint8_t *out, size_t *outlen)
{ {
size_t DATA_UNIT_SIZE = ctx->data_unit_size; size_t DATA_UNIT_SIZE;
size_t left; size_t left;
if (!ctx || (!in && inlen) || !out || !outlen) {
error_print();
return -1;
}
if (!ctx->block || ctx->data_unit_size < SM4_BLOCK_SIZE) {
error_print();
return -1;
}
DATA_UNIT_SIZE = ctx->data_unit_size;
if (ctx->block_nbytes >= DATA_UNIT_SIZE) { if (ctx->block_nbytes >= DATA_UNIT_SIZE) {
error_print(); error_print();
return -1; return -1;
} }
*outlen = 0; *outlen = 0;
if (!in || !inlen) {
return 1;
}
if (ctx->block_nbytes) { if (ctx->block_nbytes) {
error_print();
left = DATA_UNIT_SIZE - ctx->block_nbytes; left = DATA_UNIT_SIZE - ctx->block_nbytes;
if (inlen < left) { if (inlen < left) {
memcpy(ctx->block + ctx->block_nbytes, in, inlen); memcpy(ctx->block + ctx->block_nbytes, in, inlen);
@@ -300,7 +342,16 @@ int sm4_xts_decrypt_update(SM4_XTS_CTX *ctx,
int sm4_xts_decrypt_finish(SM4_XTS_CTX *ctx, uint8_t *out, size_t *outlen) int sm4_xts_decrypt_finish(SM4_XTS_CTX *ctx, uint8_t *out, size_t *outlen)
{ {
size_t DATA_UNIT_SIZE = ctx->data_unit_size; size_t DATA_UNIT_SIZE;
if (!ctx || !out || !outlen) {
error_print();
return -1;
}
if (!ctx->block || ctx->data_unit_size < SM4_BLOCK_SIZE) {
error_print();
return -1;
}
DATA_UNIT_SIZE = ctx->data_unit_size;
if (ctx->block_nbytes >= DATA_UNIT_SIZE) { if (ctx->block_nbytes >= DATA_UNIT_SIZE) {
error_print(); error_print();
return -1; return -1;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -39,18 +39,27 @@ static int test_sm4_cbc_mac(void)
sm4_cbc_encrypt_blocks(&sm4_key, iv, m, sizeof(m)/16, c); sm4_cbc_encrypt_blocks(&sm4_key, iv, m, sizeof(m)/16, c);
memcpy(mac1, c + sizeof(m) - 16, 16); memcpy(mac1, c + sizeof(m) - 16, 16);
sm4_cbc_mac_init(&ctx, key); if (sm4_cbc_mac_init(&ctx, key) != 1) {
error_print();
return -1;
}
p = m; p = m;
len = 0; len = 0;
left = sizeof(m); left = sizeof(m);
while (left) { while (left) {
len = left < len ? left : len; len = left < len ? left : len;
sm4_cbc_mac_update(&ctx, p, len); if (sm4_cbc_mac_update(&ctx, p, len) != 1) {
error_print();
return -1;
}
p += len; p += len;
left -= len; left -= len;
len++; len++;
} }
sm4_cbc_mac_finish(&ctx, mac2); if (sm4_cbc_mac_finish(&ctx, mac2) != 1) {
error_print();
return -1;
}
if (memcmp(mac1, mac2, 16)) { if (memcmp(mac1, mac2, 16)) {
error_print(); error_print();
return -1; return -1;
@@ -62,18 +71,27 @@ static int test_sm4_cbc_mac(void)
sm4_cbc_encrypt_blocks(&sm4_key, iv, m, sizeof(m)/16, c); sm4_cbc_encrypt_blocks(&sm4_key, iv, m, sizeof(m)/16, c);
memcpy(mac1, c + sizeof(m) - 16, 16); memcpy(mac1, c + sizeof(m) - 16, 16);
sm4_cbc_mac_init(&ctx, key); if (sm4_cbc_mac_init(&ctx, key) != 1) {
error_print();
return -1;
}
p = m; p = m;
len = 0; len = 0;
left = sizeof(m) - 1; left = sizeof(m) - 1;
while (left) { while (left) {
len = left < len ? left : len; len = left < len ? left : len;
sm4_cbc_mac_update(&ctx, p, len); if (sm4_cbc_mac_update(&ctx, p, len) != 1) {
error_print();
return -1;
}
p += len; p += len;
left -= len; left -= len;
len++; len++;
} }
sm4_cbc_mac_finish(&ctx, mac2); if (sm4_cbc_mac_finish(&ctx, mac2) != 1) {
error_print();
return -1;
}
if (memcmp(mac1, mac2, 16)) { if (memcmp(mac1, mac2, 16)) {
error_print(); error_print();
return -1; return -1;
@@ -83,8 +101,64 @@ static int test_sm4_cbc_mac(void)
return 1; return 1;
} }
static int test_sm4_cbc_mac_args(void)
{
SM4_CBC_MAC_CTX ctx;
uint8_t key[16] = {0};
uint8_t data[16] = {0};
uint8_t mac[16];
if (sm4_cbc_mac_init(NULL, key) != -1
|| sm4_cbc_mac_init(&ctx, NULL) != -1) {
error_print();
return -1;
}
if (sm4_cbc_mac_init(&ctx, key) != 1
|| sm4_cbc_mac_update(NULL, data, sizeof(data)) != -1
|| sm4_cbc_mac_update(&ctx, NULL, sizeof(data)) != -1
|| sm4_cbc_mac_update(&ctx, NULL, 0) != 1
|| sm4_cbc_mac_finish(NULL, mac) != -1
|| sm4_cbc_mac_finish(&ctx, NULL) != -1) {
error_print();
return -1;
}
ctx.ivlen = 16;
if (sm4_cbc_mac_update(&ctx, data, sizeof(data)) != -1
|| sm4_cbc_mac_finish(&ctx, mac) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_cbc_mac_finish_repeat(void)
{
SM4_CBC_MAC_CTX ctx;
uint8_t key[16] = {0};
uint8_t data[15] = {0};
uint8_t mac1[16];
uint8_t mac2[16];
if (sm4_cbc_mac_init(&ctx, key) != 1
|| sm4_cbc_mac_update(&ctx, data, sizeof(data)) != 1
|| sm4_cbc_mac_finish(&ctx, mac1) != 1
|| sm4_cbc_mac_finish(&ctx, mac2) != 1
|| memcmp(mac1, mac2, sizeof(mac1)) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void) int main(void)
{ {
if (test_sm4_cbc_mac() != 1) { error_print(); return -1; } if (test_sm4_cbc_mac() != 1) { error_print(); return -1; }
if (test_sm4_cbc_mac_args() != 1) { error_print(); return -1; }
if (test_sm4_cbc_mac_finish_repeat() != 1) { error_print(); return -1; }
return 0; return 0;
} }

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -209,6 +209,98 @@ static int test_sm4_cbc_padding(void)
return 1; return 1;
} }
static int test_sm4_cbc_args(void)
{
SM4_KEY enc_key;
SM4_KEY dec_key;
SM4_CBC_CTX ctx;
uint8_t key[16] = {0};
uint8_t iv[16] = {0};
uint8_t in[16] = {0};
uint8_t out[32];
size_t outlen;
sm4_set_encrypt_key(&enc_key, key);
sm4_set_decrypt_key(&dec_key, key);
if (sm4_cbc_padding_encrypt(NULL, iv, in, sizeof(in), out, &outlen) != -1
|| sm4_cbc_padding_encrypt(&enc_key, NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cbc_padding_encrypt(&enc_key, iv, NULL, 1, out, &outlen) != -1
|| sm4_cbc_padding_encrypt(&enc_key, iv, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cbc_padding_encrypt(&enc_key, iv, in, sizeof(in), out, NULL) != -1) {
error_print();
return -1;
}
outlen = 0;
if (sm4_cbc_padding_encrypt(&enc_key, iv, NULL, 0, out, &outlen) != 1
|| outlen != SM4_BLOCK_SIZE) {
error_print();
return -1;
}
if (sm4_cbc_padding_encrypt(&enc_key, iv, in, sizeof(in), out, &outlen) != 1
|| outlen != 2 * SM4_BLOCK_SIZE) {
error_print();
return -1;
}
out[outlen - 1] ^= 1;
memset(in, 0xa5, sizeof(in));
if (sm4_cbc_padding_decrypt(&dec_key, iv, out, outlen, in, &outlen) == 1) {
error_print();
return -1;
}
for (outlen = 0; outlen < sizeof(in); outlen++) {
if (in[outlen] != 0xa5) {
error_print();
return -1;
}
}
outlen = 0;
if (sm4_cbc_padding_encrypt(&enc_key, iv, NULL, 0, out, &outlen) != 1
|| outlen != SM4_BLOCK_SIZE) {
error_print();
return -1;
}
if (sm4_cbc_padding_decrypt(NULL, iv, out, outlen, in, &outlen) != -1
|| sm4_cbc_padding_decrypt(&dec_key, NULL, out, outlen, in, &outlen) != -1
|| sm4_cbc_padding_decrypt(&dec_key, iv, NULL, 1, in, &outlen) != -1
|| sm4_cbc_padding_decrypt(&dec_key, iv, out, outlen, NULL, &outlen) != -1
|| sm4_cbc_padding_decrypt(&dec_key, iv, out, outlen, in, NULL) != -1) {
error_print();
return -1;
}
outlen = 123;
if (sm4_cbc_padding_decrypt(&dec_key, iv, NULL, 0, in, &outlen) != -1) {
error_print();
return -1;
}
if (sm4_cbc_encrypt_init(&ctx, key, iv) != 1
|| sm4_cbc_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cbc_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cbc_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1) {
error_print();
return -1;
}
if (sm4_cbc_decrypt_init(&ctx, key, iv) != 1
|| sm4_cbc_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cbc_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cbc_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_cbc_padding_openssl(void) static int test_sm4_cbc_padding_openssl(void)
{ {
size_t i; size_t i;
@@ -342,6 +434,20 @@ static int test_sm4_cbc_ctx(void)
return -1; return -1;
} }
// check in-place decrypt
memcpy(pbuf, cbuf, clen);
if (sm4_cbc_decrypt_init(&dec_ctx, key, iv) != 1
|| sm4_cbc_decrypt_update(&dec_ctx, pbuf, clen, pbuf, &plen) != 1
|| sm4_cbc_decrypt_finish(&dec_ctx, pbuf + plen, &len) != 1) {
error_print();
return -1;
}
plen += len;
if (plen != mlen || memcmp(pbuf, mbuf, mlen) != 0) {
error_print();
return -1;
}
// second test // second test
@@ -423,6 +529,7 @@ int main(void)
if (test_sm4_cbc() != 1) goto err; if (test_sm4_cbc() != 1) goto err;
if (test_sm4_cbc_test_vectors() != 1) goto err; if (test_sm4_cbc_test_vectors() != 1) goto err;
if (test_sm4_cbc_padding() != 1) goto err; if (test_sm4_cbc_padding() != 1) goto err;
if (test_sm4_cbc_args() != 1) goto err;
if (test_sm4_cbc_padding_openssl() != 1) goto err; if (test_sm4_cbc_padding_openssl() != 1) goto err;
if (test_sm4_cbc_ctx() != 1) goto err; if (test_sm4_cbc_ctx() != 1) goto err;
printf("%s all tests passed\n", __FILE__); printf("%s all tests passed\n", __FILE__);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -87,6 +87,15 @@ static int test_sm4_ccm_test_vectors(void)
"aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa", "aaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbccccccccccccccccddddddddddddddddeeeeeeeeeeeeeeeeffffffffffffffffeeeeeeeeeeeeeeeeaaaaaaaaaaaaaaaa",
"48af93501fa62adbcd414cce6034d895dda1bf8f132f042098661572e7483094fd12e518ce062c98acee28d95df4416bed31a2f04476c18bb40c84a74b97dc5b", "48af93501fa62adbcd414cce6034d895dda1bf8f132f042098661572e7483094fd12e518ce062c98acee28d95df4416bed31a2f04476c18bb40c84a74b97dc5b",
}, },
{
"openssl-sm4-ccm-aad-padding-boundary",
"0123456789abcdeffedcba9876543210",
"000102030405060708090a0b",
"101112131415161718191a1b1c1d",
"7290e28b5fa29391036f06a0",
"202122232425262728292a2b2c2d2e",
"374bfae945b38c4082d62a0b4304a0",
},
}; };
uint8_t key[16]; uint8_t key[16];
@@ -177,6 +186,66 @@ static int test_sm4_ccm_test_vectors(void)
} }
static int test_sm4_ccm_aad_padding_bug(void)
{
const char *hex_key = "0123456789abcdeffedcba9876543210";
const char *hex_iv = "000102030405060708090a0b";
const char *hex_aad = "101112131415161718191a1b1c1d";
const char *hex_msg = "202122232425262728292a2b2c2d2e";
const char *hex_ct = "374bfae945b38c4082d62a0b4304a0";
const char *hex_tag = "7290e28b5fa29391036f06a0";
SM4_KEY sm4_key;
uint8_t key[16];
uint8_t iv[16];
uint8_t aad[16];
uint8_t msg[16];
uint8_t ct[16];
uint8_t tag[16];
uint8_t out[16];
uint8_t dec[16];
uint8_t mac[16];
size_t keylen, ivlen, aadlen, msglen, ctlen, taglen;
if (hex_to_bytes(hex_key, strlen(hex_key), key, &keylen) != 1
|| hex_to_bytes(hex_iv, strlen(hex_iv), iv, &ivlen) != 1
|| hex_to_bytes(hex_aad, strlen(hex_aad), aad, &aadlen) != 1
|| hex_to_bytes(hex_msg, strlen(hex_msg), msg, &msglen) != 1
|| hex_to_bytes(hex_ct, strlen(hex_ct), ct, &ctlen) != 1
|| hex_to_bytes(hex_tag, strlen(hex_tag), tag, &taglen) != 1) {
error_print();
return -1;
}
/*
* Regression for `alen + aadlen % 16`.
* Short AAD uses alen = 2. Here aadlen = 14, so
* `(alen + aadlen) % 16` is 0 and no zero padding block is added.
*/
if (aadlen != 14 || (2 + aadlen) % 16 != 0) {
error_print();
return -1;
}
sm4_set_encrypt_key(&sm4_key, key);
if (sm4_ccm_encrypt(&sm4_key, iv, ivlen, aad, aadlen,
msg, msglen, out, taglen, mac) != 1
|| ctlen != msglen
|| memcmp(out, ct, ctlen) != 0
|| memcmp(mac, tag, taglen) != 0) {
error_print();
return -1;
}
if (sm4_ccm_decrypt(&sm4_key, iv, ivlen, aad, aadlen,
ct, ctlen, tag, taglen, dec) != 1
|| memcmp(dec, msg, msglen) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_ccm_wycheproof(void) static int test_sm4_ccm_wycheproof(void)
{ {
size_t i; size_t i;
@@ -242,6 +311,59 @@ static int test_sm4_ccm_wycheproof(void)
return 1; return 1;
} }
static int test_sm4_ccm_args(void)
{
SM4_KEY sm4_key;
uint8_t key[16] = {0};
uint8_t iv[12] = {0};
uint8_t aad[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
uint8_t dec[16];
uint8_t tag[16];
sm4_set_encrypt_key(&sm4_key, key);
if (sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), NULL, 0, NULL, 0, out, 16, tag) != 1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), NULL, 0, NULL, 0, tag, 16, dec) != 1) {
error_print();
return -1;
}
if (sm4_ccm_encrypt(NULL, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, NULL, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, 6, aad, sizeof(aad), in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, 14, aad, sizeof(aad), in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), NULL, 1, in, sizeof(in), out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), NULL, 1, out, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), NULL, 16, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 16, NULL) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 3, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 17, tag) != -1
|| sm4_ccm_encrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), out, 5, tag) != -1) {
error_print();
return -1;
}
if (sm4_ccm_decrypt(NULL, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, NULL, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, 6, aad, sizeof(aad), in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, 14, aad, sizeof(aad), in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), NULL, 1, in, sizeof(in), tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), NULL, 1, tag, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), NULL, 16, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 16, NULL) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 3, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 17, out) != -1
|| sm4_ccm_decrypt(&sm4_key, iv, sizeof(iv), aad, sizeof(aad), in, sizeof(in), tag, 5, out) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int speed_sm4_ccm_encrypt(void) static int speed_sm4_ccm_encrypt(void)
{ {
SM4_KEY sm4_key; SM4_KEY sm4_key;
@@ -275,7 +397,9 @@ int main(void)
{ {
if (test_sm4_ccm() != 1) goto err; if (test_sm4_ccm() != 1) goto err;
if (test_sm4_ccm_test_vectors() != 1) goto err; if (test_sm4_ccm_test_vectors() != 1) goto err;
if (test_sm4_ccm_aad_padding_bug() != 1) goto err;
if (test_sm4_ccm_wycheproof() != 1) goto err; if (test_sm4_ccm_wycheproof() != 1) goto err;
if (test_sm4_ccm_args() != 1) goto err;
#if ENABLE_TEST_SPEED #if ENABLE_TEST_SPEED
if (speed_sm4_ccm_encrypt() != 1) goto err; if (speed_sm4_ccm_encrypt() != 1) goto err;
#endif #endif

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -260,11 +260,69 @@ static int test_sm4_cfb_ctx(void)
return 1; return 1;
} }
static int test_sm4_cfb_args(void)
{
SM4_CFB_CTX ctx;
uint8_t key[16] = {0};
uint8_t iv[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
size_t outlen;
if (sm4_cfb_encrypt_init(NULL, SM4_CFB_128, key, iv) != -1
|| sm4_cfb_encrypt_init(&ctx, 0, key, iv) != -1
|| sm4_cfb_encrypt_init(&ctx, SM4_BLOCK_SIZE + 1, key, iv) != -1
|| sm4_cfb_encrypt_init(&ctx, SM4_CFB_128, NULL, iv) != -1
|| sm4_cfb_encrypt_init(&ctx, SM4_CFB_128, key, NULL) != -1
|| sm4_cfb_decrypt_init(NULL, SM4_CFB_128, key, iv) != -1
|| sm4_cfb_decrypt_init(&ctx, 0, key, iv) != -1
|| sm4_cfb_decrypt_init(&ctx, SM4_BLOCK_SIZE + 1, key, iv) != -1
|| sm4_cfb_decrypt_init(&ctx, SM4_CFB_128, NULL, iv) != -1
|| sm4_cfb_decrypt_init(&ctx, SM4_CFB_128, key, NULL) != -1) {
error_print();
return -1;
}
if (sm4_cfb_encrypt_init(&ctx, SM4_CFB_128, key, iv) != 1
|| sm4_cfb_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cfb_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_cfb_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cfb_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_cfb_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cfb_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cfb_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_cfb_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_cfb_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_cfb_decrypt_init(&ctx, SM4_CFB_128, key, iv) != 1
|| sm4_cfb_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cfb_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_cfb_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cfb_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_cfb_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cfb_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cfb_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_cfb_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_cfb_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void) int main(void)
{ {
if (test_sm4_cfb() != 1) goto err; if (test_sm4_cfb() != 1) goto err;
if (test_sm4_cfb_test_vectors() != 1) goto err; if (test_sm4_cfb_test_vectors() != 1) goto err;
if (test_sm4_cfb_ctx() != 1) goto err; if (test_sm4_cfb_ctx() != 1) goto err;
if (test_sm4_cfb_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__); printf("%s all tests passed\n", __FILE__);
return 0; return 0;
err: err:

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -425,6 +425,96 @@ static int test_sm4_ctr_ctx_multi_updates(void)
return 1; return 1;
} }
static int test_sm4_ctr_args(void)
{
SM4_CTR_CTX ctx;
uint8_t key[16] = {0};
uint8_t ctr[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
size_t outlen;
if (sm4_ctr_encrypt_init(NULL, key, ctr) != -1
|| sm4_ctr_encrypt_init(&ctx, NULL, ctr) != -1
|| sm4_ctr_encrypt_init(&ctx, key, NULL) != -1
|| sm4_ctr32_encrypt_init(NULL, key, ctr) != -1
|| sm4_ctr32_encrypt_init(&ctx, NULL, ctr) != -1
|| sm4_ctr32_encrypt_init(&ctx, key, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ctr_encrypt_init(&ctx, key, ctr) != 1
|| sm4_ctr_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ctr_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ctr_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ctr_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ctr_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ctr_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ctr_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ctr_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ctr_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ctr32_encrypt_init(&ctx, key, ctr) != 1
|| sm4_ctr32_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ctr32_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ctr32_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ctr32_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ctr32_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ctr32_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ctr32_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ctr32_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ctr32_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_ctr_finish_no_extra_counter(void)
{
SM4_CTR_CTX ctx;
uint8_t key[16] = {0};
uint8_t ctr[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
uint8_t expected_ctr[16];
size_t outlen;
memcpy(expected_ctr, ctr, sizeof(expected_ctr));
expected_ctr[15]++;
if (sm4_ctr_encrypt_init(&ctx, key, ctr) != 1
|| sm4_ctr_encrypt_update(&ctx, in, sizeof(in), out, &outlen) != 1
|| outlen != sizeof(in)
|| sm4_ctr_encrypt_finish(&ctx, out, &outlen) != 1
|| outlen != 0
|| memcmp(ctx.ctr, expected_ctr, sizeof(expected_ctr)) != 0) {
error_print();
return -1;
}
if (sm4_ctr32_encrypt_init(&ctx, key, ctr) != 1
|| sm4_ctr32_encrypt_update(&ctx, in, sizeof(in), out, &outlen) != 1
|| outlen != sizeof(in)
|| sm4_ctr32_encrypt_finish(&ctx, out, &outlen) != 1
|| outlen != 0
|| memcmp(ctx.ctr, expected_ctr, sizeof(expected_ctr)) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void) int main(void)
{ {
if (test_sm4_ctr() != 1) goto err; if (test_sm4_ctr() != 1) goto err;
@@ -433,6 +523,8 @@ int main(void)
if (test_sm4_ctr_iv_overflow() != 1) goto err; if (test_sm4_ctr_iv_overflow() != 1) goto err;
if (test_sm4_ctr_ctx() != 1) goto err; if (test_sm4_ctr_ctx() != 1) goto err;
if (test_sm4_ctr_ctx_multi_updates() != 1) goto err; if (test_sm4_ctr_ctx_multi_updates() != 1) goto err;
if (test_sm4_ctr_args() != 1) goto err;
if (test_sm4_ctr_finish_no_extra_counter() != 1) goto err;
printf("%s all tests passed\n", __FILE__); printf("%s all tests passed\n", __FILE__);
return 0; return 0;
err: err:

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -180,11 +180,62 @@ static int test_sm4_ecb_ctx(void)
return 1; return 1;
} }
static int test_sm4_ecb_args(void)
{
SM4_ECB_CTX ctx;
uint8_t key[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
size_t outlen;
if (sm4_ecb_encrypt_init(NULL, key) != -1
|| sm4_ecb_encrypt_init(&ctx, NULL) != -1
|| sm4_ecb_decrypt_init(NULL, key) != -1
|| sm4_ecb_decrypt_init(&ctx, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ecb_encrypt_init(&ctx, key) != 1
|| sm4_ecb_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ecb_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ecb_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ecb_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ecb_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ecb_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ecb_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ecb_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ecb_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ecb_decrypt_init(&ctx, key) != 1
|| sm4_ecb_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ecb_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ecb_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ecb_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ecb_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ecb_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ecb_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_ecb_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ecb_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void) int main(void)
{ {
if (test_sm4_ecb() != 1) goto err; if (test_sm4_ecb() != 1) goto err;
if (test_sm4_ecb_test_vectors() != 1) goto err; if (test_sm4_ecb_test_vectors() != 1) goto err;
if (test_sm4_ecb_ctx() != 1) goto err; if (test_sm4_ecb_ctx() != 1) goto err;
if (test_sm4_ecb_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__); printf("%s all tests passed\n", __FILE__);
return 0; return 0;
err: err:

View File

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

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -246,11 +246,47 @@ static int test_sm4_ofb_ctx(void)
return 1; return 1;
} }
static int test_sm4_ofb_args(void)
{
SM4_OFB_CTX ctx;
uint8_t key[16] = {0};
uint8_t iv[16] = {0};
uint8_t in[16] = {0};
uint8_t out[16];
size_t outlen;
if (sm4_ofb_encrypt_init(NULL, key, iv) != -1
|| sm4_ofb_encrypt_init(&ctx, NULL, iv) != -1
|| sm4_ofb_encrypt_init(&ctx, key, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ofb_encrypt_init(&ctx, key, iv) != 1
|| sm4_ofb_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ofb_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ofb_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ofb_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ofb_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ofb_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ofb_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ofb_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ofb_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void) int main(void)
{ {
if (test_sm4_ofb() != 1) goto err; if (test_sm4_ofb() != 1) goto err;
if (test_sm4_ofb_test_vectors() != 1) goto err; if (test_sm4_ofb_test_vectors() != 1) goto err;
if (test_sm4_ofb_ctx() != 1) goto err; if (test_sm4_ofb_ctx() != 1) goto err;
if (test_sm4_ofb_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__); printf("%s all tests passed\n", __FILE__);
return 0; return 0;
err: err:

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -260,10 +260,140 @@ static int test_sm4_ctr_sm3_hmac(void)
return 1; return 1;
} }
static int test_sm4_cbc_sm3_hmac_args(void)
{
SM4_CBC_SM3_HMAC_CTX ctx;
uint8_t key[SM4_CBC_SM3_HMAC_KEY_SIZE] = {0};
uint8_t iv[SM4_CBC_SM3_HMAC_IV_SIZE] = {0};
uint8_t aad[16] = {0};
uint8_t in[64] = {0};
uint8_t out[128];
size_t outlen;
if (sm4_cbc_sm3_hmac_encrypt_init(NULL, key, iv, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_encrypt_init(&ctx, NULL, iv, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_encrypt_init(&ctx, key, NULL, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_encrypt_init(&ctx, key, iv, NULL, sizeof(aad)) != -1
|| sm4_cbc_sm3_hmac_decrypt_init(NULL, key, iv, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_decrypt_init(&ctx, NULL, iv, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_decrypt_init(&ctx, key, NULL, NULL, 0) != -1
|| sm4_cbc_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, sizeof(aad)) != -1) {
error_print();
return -1;
}
if (sm4_cbc_sm3_hmac_encrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_cbc_sm3_hmac_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cbc_sm3_hmac_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_cbc_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_cbc_sm3_hmac_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_cbc_sm3_hmac_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
outlen = 123;
if (sm4_cbc_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_cbc_sm3_hmac_decrypt_update(&ctx, in, 1, out, &outlen) != 1
|| outlen != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_ctr_sm3_hmac_args(void)
{
SM4_CTR_SM3_HMAC_CTX ctx;
uint8_t key[SM4_CTR_SM3_HMAC_KEY_SIZE] = {0};
uint8_t iv[SM4_CTR_SM3_HMAC_IV_SIZE] = {0};
uint8_t aad[16] = {0};
uint8_t in[64] = {0};
uint8_t out[128];
size_t outlen;
if (sm4_ctr_sm3_hmac_encrypt_init(NULL, key, iv, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_encrypt_init(&ctx, NULL, iv, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_encrypt_init(&ctx, key, NULL, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_encrypt_init(&ctx, key, iv, NULL, sizeof(aad)) != -1
|| sm4_ctr_sm3_hmac_decrypt_init(NULL, key, iv, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_decrypt_init(&ctx, NULL, iv, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_decrypt_init(&ctx, key, NULL, NULL, 0) != -1
|| sm4_ctr_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, sizeof(aad)) != -1) {
error_print();
return -1;
}
if (sm4_ctr_sm3_hmac_encrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_ctr_sm3_hmac_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ctr_sm3_hmac_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_encrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
if (sm4_ctr_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_ctr_sm3_hmac_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_ctr_sm3_hmac_decrypt_finish(&ctx, out, NULL) != -1) {
error_print();
return -1;
}
outlen = 123;
if (sm4_ctr_sm3_hmac_decrypt_init(&ctx, key, iv, NULL, 0) != 1
|| sm4_ctr_sm3_hmac_decrypt_update(&ctx, in, 1, out, &outlen) != 1
|| outlen != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void) int main(void)
{ {
if (test_sm4_cbc_sm3_hmac() != 1) goto err; if (test_sm4_cbc_sm3_hmac() != 1) goto err;
if (test_sm4_ctr_sm3_hmac() != 1) goto err; if (test_sm4_ctr_sm3_hmac() != 1) goto err;
if (test_sm4_cbc_sm3_hmac_args() != 1) goto err;
if (test_sm4_ctr_sm3_hmac_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__); printf("%s all tests passed\n", __FILE__);
return 0; return 0;
err: err:

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -163,10 +163,176 @@ static int test_sm4_xts_test_vectors(void)
return 1; return 1;
} }
static int test_sm4_xts_ctx(void)
{
SM4_XTS_CTX ctx;
uint8_t key[32];
uint8_t iv[16];
uint8_t plaintext[64];
uint8_t ciphertext[64];
uint8_t decrypted[64];
size_t outlen, total;
rand_bytes(key, sizeof(key));
rand_bytes(iv, sizeof(iv));
rand_bytes(plaintext, sizeof(plaintext));
if (sm4_xts_encrypt_init(&ctx, key, iv, 32) != 1
|| sm4_xts_encrypt_update(&ctx, plaintext, 7, ciphertext, &outlen) != 1
|| outlen != 0
|| sm4_xts_encrypt_update(&ctx, NULL, 0, ciphertext, &outlen) != 1
|| outlen != 0
|| sm4_xts_encrypt_update(&ctx, plaintext + 7, 25, ciphertext, &outlen) != 1
|| outlen != 32) {
error_print();
return -1;
}
total = outlen;
if (sm4_xts_encrypt_update(&ctx, plaintext + 32, 32, ciphertext + total, &outlen) != 1
|| outlen != 32) {
error_print();
return -1;
}
total += outlen;
if (sm4_xts_encrypt_finish(&ctx, ciphertext + total, &outlen) != 1
|| outlen != 0
|| total != sizeof(plaintext)) {
error_print();
return -1;
}
if (sm4_xts_decrypt_init(&ctx, key, iv, 32) != 1
|| sm4_xts_decrypt_update(&ctx, ciphertext, 5, decrypted, &outlen) != 1
|| outlen != 0
|| sm4_xts_decrypt_update(&ctx, NULL, 0, decrypted, &outlen) != 1
|| outlen != 0
|| sm4_xts_decrypt_update(&ctx, ciphertext + 5, 27, decrypted, &outlen) != 1
|| outlen != 32) {
error_print();
return -1;
}
total = outlen;
if (sm4_xts_decrypt_update(&ctx, ciphertext + 32, 32, decrypted + total, &outlen) != 1
|| outlen != 32) {
error_print();
return -1;
}
total += outlen;
if (sm4_xts_decrypt_finish(&ctx, decrypted + total, &outlen) != 1
|| outlen != 0
|| total != sizeof(plaintext)
|| memcmp(decrypted, plaintext, sizeof(plaintext)) != 0) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
static int test_sm4_xts_args(void)
{
SM4_KEY key1;
SM4_KEY key2;
SM4_XTS_CTX ctx;
uint8_t key[32] = {0};
uint8_t tweak[16] = {0};
uint8_t in[32] = {0};
uint8_t out[32];
size_t outlen;
sm4_set_encrypt_key(&key1, key);
sm4_set_encrypt_key(&key2, key + 16);
if (sm4_xts_encrypt(NULL, &key2, tweak, in, sizeof(in), out) != -1
|| sm4_xts_encrypt(&key1, NULL, tweak, in, sizeof(in), out) != -1
|| sm4_xts_encrypt(&key1, &key2, NULL, in, sizeof(in), out) != -1
|| sm4_xts_encrypt(&key1, &key2, tweak, NULL, sizeof(in), out) != -1
|| sm4_xts_encrypt(&key1, &key2, tweak, in, sizeof(in), NULL) != -1
|| sm4_xts_encrypt(&key1, &key2, tweak, NULL, 0, out) != -1
|| sm4_xts_encrypt(&key1, &key2, tweak, in, SM4_BLOCK_SIZE - 1, out) != -1) {
error_print();
return -1;
}
sm4_set_decrypt_key(&key1, key);
if (sm4_xts_decrypt(NULL, &key2, tweak, in, sizeof(in), out) != -1
|| sm4_xts_decrypt(&key1, NULL, tweak, in, sizeof(in), out) != -1
|| sm4_xts_decrypt(&key1, &key2, NULL, in, sizeof(in), out) != -1
|| sm4_xts_decrypt(&key1, &key2, tweak, NULL, sizeof(in), out) != -1
|| sm4_xts_decrypt(&key1, &key2, tweak, in, sizeof(in), NULL) != -1
|| sm4_xts_decrypt(&key1, &key2, tweak, NULL, 0, out) != -1
|| sm4_xts_decrypt(&key1, &key2, tweak, in, SM4_BLOCK_SIZE - 1, out) != -1) {
error_print();
return -1;
}
if (sm4_xts_encrypt_init(NULL, key, tweak, 32) != -1
|| sm4_xts_encrypt_init(&ctx, NULL, tweak, 32) != -1
|| sm4_xts_encrypt_init(&ctx, key, NULL, 32) != -1
|| sm4_xts_encrypt_init(&ctx, key, tweak, SM4_BLOCK_SIZE - 1) != -1) {
error_print();
return -1;
}
if (sm4_xts_encrypt_init(&ctx, key, tweak, 32) != 1
|| sm4_xts_encrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_xts_encrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_xts_encrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_xts_encrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_xts_encrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_xts_encrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_xts_encrypt_finish(NULL, out, &outlen) != -1
|| sm4_xts_encrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_xts_encrypt_finish(&ctx, out, NULL) != -1
|| sm4_xts_encrypt_finish(&ctx, out, &outlen) != 1
|| outlen != 0) {
error_print();
return -1;
}
if (sm4_xts_decrypt_init(NULL, key, tweak, 32) != -1
|| sm4_xts_decrypt_init(&ctx, NULL, tweak, 32) != -1
|| sm4_xts_decrypt_init(&ctx, key, NULL, 32) != -1
|| sm4_xts_decrypt_init(&ctx, key, tweak, SM4_BLOCK_SIZE - 1) != -1) {
error_print();
return -1;
}
if (sm4_xts_decrypt_init(&ctx, key, tweak, 32) != 1
|| sm4_xts_decrypt_update(NULL, in, sizeof(in), out, &outlen) != -1
|| sm4_xts_decrypt_update(&ctx, NULL, 1, out, &outlen) != -1
|| sm4_xts_decrypt_update(&ctx, in, sizeof(in), NULL, &outlen) != -1
|| sm4_xts_decrypt_update(&ctx, in, sizeof(in), out, NULL) != -1
|| sm4_xts_decrypt_update(&ctx, NULL, 0, out, &outlen) != 1
|| outlen != 0
|| sm4_xts_decrypt_update(&ctx, NULL, 0, NULL, &outlen) != -1
|| sm4_xts_decrypt_finish(NULL, out, &outlen) != -1
|| sm4_xts_decrypt_finish(&ctx, NULL, &outlen) != -1
|| sm4_xts_decrypt_finish(&ctx, out, NULL) != -1
|| sm4_xts_decrypt_finish(&ctx, out, &outlen) != 1
|| outlen != 0) {
error_print();
return -1;
}
if (sm4_xts_encrypt_init(&ctx, key, tweak, 32) != 1
|| sm4_xts_encrypt_update(&ctx, in, 16, out, &outlen) != 1
|| outlen != 0
|| sm4_xts_encrypt_finish(&ctx, out, &outlen) != -1) {
error_print();
return -1;
}
printf("%s() ok\n", __FUNCTION__);
return 1;
}
int main(void) int main(void)
{ {
if (test_sm4_xts() != 1) goto err; if (test_sm4_xts() != 1) goto err;
if (test_sm4_xts_test_vectors() != 1) goto err; if (test_sm4_xts_test_vectors() != 1) goto err;
if (test_sm4_xts_ctx() != 1) goto err;
if (test_sm4_xts_args() != 1) goto err;
printf("%s all tests passed\n", __FILE__); printf("%s all tests passed\n", __FILE__);
return 0; return 0;
err: err:

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -686,7 +686,7 @@ bad:
case SM4_MODE_OFB: rv = sm4_ofb_encrypt_update(&sm4_ctx.ofb, inbuf, inlen, outbuf, &outlen); break; case SM4_MODE_OFB: rv = sm4_ofb_encrypt_update(&sm4_ctx.ofb, inbuf, inlen, outbuf, &outlen); break;
#endif #endif
#ifdef ENABLE_SM4_XTS #ifdef ENABLE_SM4_XTS
case SM4_MODE_XTS: rv = sm4_xts_encrypt_update(&sm4_ctx.xts, inbuf, inlen, outbuf, &outlen); break; case SM4_MODE_XTS: rv = sm4_xts_decrypt_update(&sm4_ctx.xts, inbuf, inlen, outbuf, &outlen); break;
#endif #endif
case SM4_MODE_GCM: rv = sm4_gcm_decrypt_update(&sm4_ctx.gcm, inbuf, inlen, outbuf, &outlen); break; case SM4_MODE_GCM: rv = sm4_gcm_decrypt_update(&sm4_ctx.gcm, inbuf, inlen, outbuf, &outlen); break;
case SM4_MODE_CBC_SM3_HMAC: rv = sm4_cbc_sm3_hmac_decrypt_update(&sm4_ctx.cbc_sm3_hmac, inbuf, inlen, outbuf, &outlen); break; case SM4_MODE_CBC_SM3_HMAC: rv = sm4_cbc_sm3_hmac_decrypt_update(&sm4_ctx.cbc_sm3_hmac, inbuf, inlen, outbuf, &outlen); break;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -84,7 +84,7 @@ int sm4_cbc_mac_main(int argc, char **argv)
} else if (!strcmp(*argv, "-key")) { } else if (!strcmp(*argv, "-key")) {
if (--argc < 1) goto bad; if (--argc < 1) goto bad;
keyhex = *(++argv); keyhex = *(++argv);
if (strlen(keyhex) > sizeof(key) * 2) { if (strlen(keyhex) != sizeof(key) * 2) {
fprintf(stderr, "gmssl %s: key should be 16 bytes\n", prog); fprintf(stderr, "gmssl %s: key should be 16 bytes\n", prog);
goto end; goto end;
} }
@@ -142,43 +142,31 @@ bad:
goto end; goto end;
} }
sm4_cbc_mac_init(&ctx, key);
/*
if (sm4_cbc_mac_init(&ctx, key) != 1) { if (sm4_cbc_mac_init(&ctx, key) != 1) {
fprintf(stderr, "gmssl %s: inner error\n", prog); fprintf(stderr, "gmssl %s: inner error\n", prog);
goto end; goto end;
} }
*/
if (in_str) { if (in_str) {
sm4_cbc_mac_update(&ctx, (uint8_t *)in_str, strlen(in_str));
/*
if (sm4_cbc_mac_update(&ctx, (uint8_t *)in_str, strlen(in_str)) != 1) { if (sm4_cbc_mac_update(&ctx, (uint8_t *)in_str, strlen(in_str)) != 1) {
fprintf(stderr, "gmssl %s: inner error\n", prog); fprintf(stderr, "gmssl %s: inner error\n", prog);
goto end; goto end;
} }
*/
} else { } else {
uint8_t buf[4096]; uint8_t buf[4096];
size_t len; size_t len;
while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) {
sm4_cbc_mac_update(&ctx, buf, len);
/*
if (sm4_cbc_mac_update(&ctx, buf, len) != 1) { if (sm4_cbc_mac_update(&ctx, buf, len) != 1) {
fprintf(stderr, "gmssl %s: inner error\n", prog); fprintf(stderr, "gmssl %s: inner error\n", prog);
goto end; goto end;
} }
*/
} }
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
} }
sm4_cbc_mac_finish(&ctx, mac);
/*
if (sm4_cbc_mac_finish(&ctx, mac) != 1) { if (sm4_cbc_mac_finish(&ctx, mac) != 1) {
fprintf(stderr, "gmssl %s: inner error\n", prog); fprintf(stderr, "gmssl %s: inner error\n", prog);
goto end; goto end;
} }
*/
if (outformat > 1) { if (outformat > 1) {
if (fwrite(mac, 1, sizeof(mac), outfp) != sizeof(mac)) { if (fwrite(mac, 1, sizeof(mac), outfp) != sizeof(mac)) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -99,7 +99,7 @@ int sm4_cbc_sm3_hmac_main(int argc, char **argv)
goto end; goto end;
} }
if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) {
fprintf(stderr, "gmssl %s: invalid key hex digits, should be %d bytes\n", prog, SM4_CBC_SM3_HMAC_IV_SIZE); fprintf(stderr, "gmssl %s: invalid key hex digits, should be %d bytes\n", prog, SM4_CBC_SM3_HMAC_KEY_SIZE);
goto end; goto end;
} }
} else if (!strcmp(*argv, "-iv")) { } else if (!strcmp(*argv, "-iv")) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -99,7 +99,7 @@ int sm4_ctr_sm3_hmac_main(int argc, char **argv)
goto end; goto end;
} }
if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) {
fprintf(stderr, "gmssl %s: invalid key hex digits, should be %d bytes\n", prog, SM4_CTR_SM3_HMAC_IV_SIZE); fprintf(stderr, "gmssl %s: invalid key hex digits, should be %d bytes\n", prog, SM4_CTR_SM3_HMAC_KEY_SIZE);
goto end; goto end;
} }
} else if (!strcmp(*argv, "-iv")) { } else if (!strcmp(*argv, "-iv")) {

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved. * Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
* *
* Licensed under the Apache License, Version 2.0 (the License); you may * Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License. * not use this file except in compliance with the License.
@@ -56,7 +56,7 @@ int sm4_xts_main(int argc, char **argv)
size_t ivlen; size_t ivlen;
FILE *infp = stdin; FILE *infp = stdin;
FILE *outfp = stdout; FILE *outfp = stdout;
SM4_XTS_CTX ctx; SM4_XTS_CTX ctx = {0};
uint8_t *buf = NULL; uint8_t *buf = NULL;
size_t buflen; size_t buflen;
size_t inlen; size_t inlen;
@@ -212,6 +212,7 @@ bad:
ret = 0; ret = 0;
end: end:
if (ctx.block) free(ctx.block);
gmssl_secure_clear(key, sizeof(key)); gmssl_secure_clear(key, sizeof(key));
gmssl_secure_clear(iv, sizeof(iv)); gmssl_secure_clear(iv, sizeof(iv));
gmssl_secure_clear(&ctx, sizeof(ctx)); gmssl_secure_clear(&ctx, sizeof(ctx));