mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-06-19 19:33:38 +08:00
Fix SM4 API bugs and change behavior
This commit is contained in:
@@ -22,6 +22,11 @@ int sm4_cbc_padding_encrypt(const SM4_KEY *key, const uint8_t piv[16],
|
||||
size_t rem = inlen % 16;
|
||||
int padding = 16 - inlen % 16;
|
||||
|
||||
if (!key || !piv || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
memcpy(iv, piv, 16);
|
||||
|
||||
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);
|
||||
*outlen = inlen - rem + 16;
|
||||
|
||||
gmssl_secure_clear(iv, sizeof(iv));
|
||||
gmssl_secure_clear(block, sizeof(block));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -48,37 +56,47 @@ int sm4_cbc_padding_decrypt(const SM4_KEY *key, const uint8_t piv[16],
|
||||
int padding;
|
||||
int i;
|
||||
|
||||
memcpy(iv, piv, 16);
|
||||
|
||||
if (inlen == 0) {
|
||||
error_puts("warning: input lenght = 0");
|
||||
return 0;
|
||||
}
|
||||
if (inlen%16 != 0 || inlen < 16) {
|
||||
error_puts("invalid cbc ciphertext length");
|
||||
if (!key || !piv || !in || !inlen || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (inlen > 16) {
|
||||
sm4_cbc_decrypt_blocks(key, iv, in, inlen/16 - 1, out);
|
||||
if (inlen % 16 != 0 || inlen < 16) {
|
||||
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);
|
||||
gmssl_secure_clear(iv, sizeof(iv));
|
||||
|
||||
padding = block[15];
|
||||
if (padding < 1 || padding > 16) {
|
||||
gmssl_secure_clear(block, sizeof(block));
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
for (i = 16 - padding; i < 16; i++) {
|
||||
if (block[i] != padding) {
|
||||
gmssl_secure_clear(block, sizeof(block));
|
||||
error_print();
|
||||
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;
|
||||
memcpy(out + inlen - 16, block, len);
|
||||
*outlen = inlen - padding;
|
||||
|
||||
gmssl_secure_clear(block, sizeof(block));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -103,19 +121,19 @@ int sm4_cbc_encrypt_update(SM4_CBC_CTX *ctx,
|
||||
size_t nblocks;
|
||||
size_t len;
|
||||
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
left = SM4_BLOCK_SIZE - ctx->block_nbytes;
|
||||
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)
|
||||
{
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = SM4_BLOCK_SIZE;
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
@@ -183,22 +197,23 @@ int sm4_cbc_decrypt_init(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)
|
||||
{
|
||||
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();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes > SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
left = SM4_BLOCK_SIZE - ctx->block_nbytes;
|
||||
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)
|
||||
{
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = SM4_BLOCK_SIZE;
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes != SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2022 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -17,15 +17,31 @@
|
||||
#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);
|
||||
memset(ctx->iv, 0, 16);
|
||||
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) {
|
||||
size_t ivleft = 16 - ctx->ivlen;
|
||||
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;
|
||||
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) {
|
||||
sm4_encrypt(&ctx->key, ctx->iv, ctx->iv);
|
||||
ctx->ivlen = 0;
|
||||
}
|
||||
memcpy(mac, ctx->iv, 16);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -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)
|
||||
{
|
||||
if (!ctx || !in || !out || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (sm4_cbc_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
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;
|
||||
|
||||
if (!ctx || !in || !out || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
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;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->maclen < SM3_HMAC_SIZE) {
|
||||
len = SM3_HMAC_SIZE - ctx->maclen;
|
||||
if (inlen <= len) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -8,10 +8,10 @@
|
||||
*/
|
||||
|
||||
|
||||
#include <gmssl/sm4.h>
|
||||
#include <gmssl/mem.h>
|
||||
#include <gmssl/sm4_cbc_mac.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)
|
||||
@@ -60,11 +60,11 @@ int sm4_ccm_encrypt(const SM4_KEY *sm4_key, const uint8_t *iv, size_t ivlen,
|
||||
uint8_t mac[16];
|
||||
size_t inlen_size;
|
||||
|
||||
if (ivlen < 7 || ivlen > 13) {
|
||||
if (!sm4_key || !iv || (!aad && aadlen) || (!in && inlen) || !out || !tag) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!aad && aadlen) {
|
||||
if (ivlen < 7 || ivlen > 13) {
|
||||
error_print();
|
||||
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, aad, aadlen);
|
||||
if (alen + aadlen % 16) {
|
||||
if ((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];
|
||||
size_t inlen_size;
|
||||
|
||||
if (ivlen < 7 || ivlen > 13) {
|
||||
if (!sm4_key || !iv || (!aad && aadlen) || (!in && inlen) || !tag || !out) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!aad && aadlen) {
|
||||
if (ivlen < 7 || ivlen > 13) {
|
||||
error_print();
|
||||
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, aad, aadlen);
|
||||
if (alen + aadlen % 16) {
|
||||
if ((alen + aadlen) % 16) {
|
||||
sm4_cbc_mac_update(&mac_ctx, zeros, 16 - (alen + aadlen)%16);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -91,19 +91,19 @@ int sm4_cfb_encrypt_update(SM4_CFB_CTX *ctx,
|
||||
size_t nblocks;
|
||||
size_t len;
|
||||
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= ctx->sbytes) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
left = ctx->sbytes - ctx->block_nbytes;
|
||||
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)
|
||||
{
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = SM4_BLOCK_SIZE;
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= ctx->sbytes) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
sm4_cfb_encrypt(&ctx->sm4_key, ctx->sbytes, ctx->iv, ctx->block, ctx->block_nbytes, out);
|
||||
if (ctx->block_nbytes) {
|
||||
sm4_cfb_encrypt(&ctx->sm4_key, ctx->sbytes, ctx->iv, ctx->block, ctx->block_nbytes, out);
|
||||
}
|
||||
*outlen = ctx->block_nbytes;
|
||||
return 1;
|
||||
}
|
||||
@@ -178,22 +176,20 @@ int sm4_cfb_decrypt_update(SM4_CFB_CTX *ctx,
|
||||
size_t nblocks;
|
||||
size_t len;
|
||||
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= ctx->sbytes) {
|
||||
error_print();
|
||||
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;
|
||||
if (inlen < left) {
|
||||
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)
|
||||
{
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = SM4_BLOCK_SIZE;
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= ctx->sbytes) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
sm4_cfb_decrypt(&ctx->sm4_key, ctx->sbytes, ctx->iv, ctx->block, ctx->block_nbytes, out);
|
||||
if (ctx->block_nbytes) {
|
||||
sm4_cfb_decrypt(&ctx->sm4_key, ctx->sbytes, ctx->iv, ctx->block, ctx->block_nbytes, out);
|
||||
}
|
||||
*outlen = ctx->block_nbytes;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -70,19 +70,19 @@ int sm4_ctr_encrypt_update(SM4_CTR_CTX *ctx,
|
||||
size_t nblocks;
|
||||
size_t len;
|
||||
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
left = SM4_BLOCK_SIZE - ctx->block_nbytes;
|
||||
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)
|
||||
{
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = SM4_BLOCK_SIZE;
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
sm4_ctr_encrypt_blocks(&ctx->sm4_key, ctx->ctr, ctx->block, 1, ctx->block);
|
||||
memcpy(out, ctx->block, ctx->block_nbytes);
|
||||
|
||||
if (ctx->block_nbytes) {
|
||||
sm4_ctr_encrypt_blocks(&ctx->sm4_key, ctx->ctr, ctx->block, 1, ctx->block);
|
||||
memcpy(out, ctx->block, ctx->block_nbytes);
|
||||
}
|
||||
*outlen = ctx->block_nbytes;
|
||||
return 1;
|
||||
}
|
||||
@@ -153,19 +152,19 @@ int sm4_ctr32_encrypt_update(SM4_CTR_CTX *ctx,
|
||||
size_t nblocks;
|
||||
size_t len;
|
||||
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
left = SM4_BLOCK_SIZE - ctx->block_nbytes;
|
||||
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)
|
||||
{
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = SM4_BLOCK_SIZE;
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
sm4_ctr32_encrypt_blocks(&ctx->sm4_key, ctx->ctr, ctx->block, 1, ctx->block);
|
||||
memcpy(out, ctx->block, ctx->block_nbytes);
|
||||
|
||||
if (ctx->block_nbytes) {
|
||||
sm4_ctr32_encrypt_blocks(&ctx->sm4_key, ctx->ctr, ctx->block, 1, ctx->block);
|
||||
memcpy(out, ctx->block, ctx->block_nbytes);
|
||||
}
|
||||
*outlen = ctx->block_nbytes;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -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)
|
||||
{
|
||||
if (!ctx || !in || !out || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (sm4_ctr_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) {
|
||||
error_print();
|
||||
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;
|
||||
|
||||
if (!ctx || !in || !out || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
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;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->maclen < SM3_HMAC_SIZE) {
|
||||
len = SM3_HMAC_SIZE - ctx->maclen;
|
||||
if (inlen <= len) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -32,19 +32,19 @@ int sm4_ecb_encrypt_update(SM4_ECB_CTX *ctx,
|
||||
size_t nblocks;
|
||||
size_t len;
|
||||
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
left = SM4_BLOCK_SIZE - ctx->block_nbytes;
|
||||
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)
|
||||
{
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
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) {
|
||||
error_print();
|
||||
return -1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -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 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) {
|
||||
error_print();
|
||||
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 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) {
|
||||
error_print();
|
||||
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)
|
||||
{
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (inlen > INT_MAX) {
|
||||
error_print();
|
||||
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();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (sm4_ctr32_encrypt_update(&ctx->enc_ctx, in, inlen, out, outlen) != 1) {
|
||||
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];
|
||||
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
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) {
|
||||
error_print();
|
||||
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)
|
||||
{
|
||||
size_t len;
|
||||
size_t datalen = 0;
|
||||
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (inlen > INT_MAX) {
|
||||
error_print();
|
||||
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) {
|
||||
error_print();
|
||||
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) {
|
||||
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);
|
||||
}
|
||||
|
||||
ctx->encedlen += inlen;
|
||||
ctx->encedlen += datalen;
|
||||
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];
|
||||
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = SM4_BLOCK_SIZE;
|
||||
return 1;
|
||||
}
|
||||
if (ctx->maclen != ctx->taglen) {
|
||||
error_print();
|
||||
return -1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -49,19 +49,19 @@ int sm4_ofb_encrypt_update(SM4_OFB_CTX *ctx,
|
||||
size_t nblocks;
|
||||
size_t len;
|
||||
|
||||
if (!ctx || !in || !outlen) {
|
||||
if (!ctx || (!in && inlen) || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = 16 * ((inlen + 15)/16);
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
left = SM4_BLOCK_SIZE - ctx->block_nbytes;
|
||||
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)
|
||||
{
|
||||
if (!ctx || !outlen) {
|
||||
if (!ctx || !out || !outlen) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (!out) {
|
||||
*outlen = SM4_BLOCK_SIZE;
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes >= SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
sm4_ofb_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, ctx->block_nbytes, out);
|
||||
if (ctx->block_nbytes) {
|
||||
sm4_ofb_encrypt(&ctx->sm4_key, ctx->iv, ctx->block, ctx->block_nbytes, out);
|
||||
}
|
||||
*outlen = ctx->block_nbytes;
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2014-2024 The GmSSL Project. All Rights Reserved.
|
||||
* Copyright 2014-2026 The GmSSL Project. All Rights Reserved.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the License); you may
|
||||
* not use this file except in compliance with the License.
|
||||
@@ -22,6 +22,10 @@ int sm4_xts_encrypt(const SM4_KEY *key1, const SM4_KEY *key2, const uint8_t twea
|
||||
size_t nblocks, i;
|
||||
gf128_t a;
|
||||
|
||||
if (!key1 || !key2 || !tweak || (!in && inlen) || !out) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (inlen < 16) {
|
||||
error_print();
|
||||
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;
|
||||
gf128_t a;
|
||||
|
||||
if (!key1 || !key2 || !tweak || (!in && inlen) || !out) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
if (inlen < 16) {
|
||||
error_print();
|
||||
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)
|
||||
{
|
||||
if (data_unit_size < SM4_BLOCK_SIZE) {
|
||||
if (!ctx || !key || !iv || data_unit_size < SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
sm4_set_encrypt_key(&ctx->key1, key);
|
||||
sm4_set_encrypt_key(&ctx->key2, key + 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,
|
||||
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;
|
||||
|
||||
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) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
left = DATA_UNIT_SIZE - ctx->block_nbytes;
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
error_print();
|
||||
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)
|
||||
{
|
||||
if (data_unit_size < SM4_BLOCK_SIZE) {
|
||||
if (!ctx || !key || !iv || data_unit_size < SM4_BLOCK_SIZE) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
memset(ctx, 0, sizeof(*ctx));
|
||||
sm4_set_decrypt_key(&ctx->key1, key);
|
||||
sm4_set_encrypt_key(&ctx->key2, key + 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,
|
||||
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;
|
||||
|
||||
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) {
|
||||
error_print();
|
||||
return -1;
|
||||
}
|
||||
*outlen = 0;
|
||||
if (!in || !inlen) {
|
||||
return 1;
|
||||
}
|
||||
if (ctx->block_nbytes) {
|
||||
error_print();
|
||||
left = DATA_UNIT_SIZE - ctx->block_nbytes;
|
||||
if (inlen < left) {
|
||||
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)
|
||||
{
|
||||
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) {
|
||||
error_print();
|
||||
return -1;
|
||||
|
||||
Reference in New Issue
Block a user