mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
Fix SM4 CFB bug when in==out, add option -sbytes to command
This commit is contained in:
@@ -13,24 +13,25 @@
|
|||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
|
|
||||||
|
|
||||||
|
// sm4_cfb_encrypt iv type is not compatible with sm4_cbc_encrypt, carefull if inlen % sbytes != 0
|
||||||
void sm4_cfb_encrypt(const SM4_KEY *key, size_t sbytes, uint8_t iv[16],
|
void sm4_cfb_encrypt(const SM4_KEY *key, size_t sbytes, uint8_t iv[16],
|
||||||
const uint8_t *in, size_t inlen, uint8_t *out)
|
const uint8_t *in, size_t inlen, uint8_t *out)
|
||||||
{
|
{
|
||||||
uint8_t block[16];
|
uint8_t block[16];
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
|
|
||||||
// assert(1 <= sbytes && sbytes <= 16);
|
|
||||||
|
|
||||||
while (inlen) {
|
while (inlen) {
|
||||||
len = inlen < sbytes ? inlen : sbytes;
|
len = inlen < sbytes ? inlen : sbytes;
|
||||||
|
|
||||||
sm4_encrypt(key, iv, block);
|
sm4_encrypt(key, iv, block);
|
||||||
|
|
||||||
gmssl_memxor(out, in, block, len);
|
gmssl_memxor(out, in, block, len);
|
||||||
|
|
||||||
// iv = (iv << sbytes) | out
|
// iv = (iv << sbytes) | out
|
||||||
for (i = 0; i < 16 - sbytes; i++) {
|
for (i = 0; i < 16 - sbytes; i++) {
|
||||||
iv[i] = iv[sbytes + i];
|
iv[i] = iv[sbytes + i];
|
||||||
}
|
}
|
||||||
memcpy(iv + i, out, len);
|
memcpy(iv + 16 - sbytes, out, len);
|
||||||
|
|
||||||
in += len;
|
in += len;
|
||||||
out += len;
|
out += len;
|
||||||
@@ -44,18 +45,19 @@ void sm4_cfb_decrypt(const SM4_KEY *key, size_t sbytes, uint8_t iv[16],
|
|||||||
uint8_t block[16];
|
uint8_t block[16];
|
||||||
size_t len, i;
|
size_t len, i;
|
||||||
|
|
||||||
// assert(1 <= sbytes && sbytes <= 16);
|
|
||||||
|
|
||||||
while (inlen) {
|
while (inlen) {
|
||||||
len = inlen < sbytes ? inlen : sbytes;
|
len = inlen < sbytes ? inlen : sbytes;
|
||||||
|
|
||||||
sm4_encrypt(key, iv, block);
|
sm4_encrypt(key, iv, block);
|
||||||
gmssl_memxor(out, in, block, len);
|
|
||||||
|
|
||||||
// iv = (iv << sbytes) | in
|
// iv = (iv << sbytes) | in
|
||||||
for (i = 0; i < 16 - sbytes; i++) {
|
for (i = 0; i < 16 - sbytes; i++) {
|
||||||
iv[i] = iv[sbytes + i];
|
iv[i] = iv[sbytes + i];
|
||||||
}
|
}
|
||||||
memcpy(iv + i, in, len);
|
memcpy(iv + 16 - sbytes, in, len);
|
||||||
|
|
||||||
|
// NOTE: must update before output, in might be changed if in == out
|
||||||
|
gmssl_memxor(out, in, block, len);
|
||||||
|
|
||||||
in += len;
|
in += len;
|
||||||
out += len;
|
out += len;
|
||||||
@@ -191,6 +193,8 @@ int sm4_cfb_decrypt_update(SM4_CFB_CTX *ctx,
|
|||||||
}
|
}
|
||||||
*outlen = 0;
|
*outlen = 0;
|
||||||
if (ctx->block_nbytes) {
|
if (ctx->block_nbytes) {
|
||||||
|
error_print();
|
||||||
|
|
||||||
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);
|
||||||
|
|||||||
@@ -13,6 +13,7 @@
|
|||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
|
|
||||||
|
|
||||||
|
// sm4_ofb_encrypt iv type is not compatible with sm4_cbc_encrypt, careful if inlen % 16 != 0
|
||||||
void sm4_ofb_encrypt(const SM4_KEY *key, uint8_t iv[16], const uint8_t *in, size_t inlen, uint8_t *out)
|
void sm4_ofb_encrypt(const SM4_KEY *key, uint8_t iv[16], const uint8_t *in, size_t inlen, uint8_t *out)
|
||||||
{
|
{
|
||||||
size_t len;
|
size_t len;
|
||||||
|
|||||||
@@ -18,12 +18,13 @@
|
|||||||
#include <gmssl/error.h>
|
#include <gmssl/error.h>
|
||||||
|
|
||||||
|
|
||||||
static const char *usage = "{-encrypt|-decrypt} -key hex -iv hex [-in file] [-out file]";
|
static const char *usage = "{-encrypt|-decrypt} -sbytes num -key hex -iv hex [-in file] [-out file]";
|
||||||
|
|
||||||
static const char *options =
|
static const char *options =
|
||||||
"\n"
|
"\n"
|
||||||
"Options\n"
|
"Options\n"
|
||||||
"\n"
|
"\n"
|
||||||
|
" -sbytes num Parameter sbytes of CFB mode, should be 1, 8 or 16, 16 by default\n"
|
||||||
" -encrypt Encrypt\n"
|
" -encrypt Encrypt\n"
|
||||||
" -decrypt Decrypt\n"
|
" -decrypt Decrypt\n"
|
||||||
" -key hex Symmetric key in HEX format\n"
|
" -key hex Symmetric key in HEX format\n"
|
||||||
@@ -36,8 +37,14 @@ static const char *options =
|
|||||||
" $ TEXT=`gmssl rand -outlen 20 -hex`\n"
|
" $ TEXT=`gmssl rand -outlen 20 -hex`\n"
|
||||||
" $ KEY=`gmssl rand -outlen 16 -hex`\n"
|
" $ KEY=`gmssl rand -outlen 16 -hex`\n"
|
||||||
" $ IV=`gmssl rand -outlen 16 -hex`\n"
|
" $ IV=`gmssl rand -outlen 16 -hex`\n"
|
||||||
" $ echo -n $TEXT | gmssl sm4_cfb -encrypt -key $KEY -iv $IV -out sm4_cfb_ciphertext.bin\n"
|
" $ echo -n $TEXT | gmssl sm4_cfb -encrypt -key $KEY -iv $IV -out sm4_cfb128_ciphertext.bin\n"
|
||||||
" $ gmssl sm4_cfb -decrypt -key $KEY -iv $IV -in sm4_cfb_ciphertext.bin\n"
|
" $ gmssl sm4_cfb -decrypt -key $KEY -iv $IV -in sm4_cfb128_ciphertext.bin\n"
|
||||||
|
"\n"
|
||||||
|
" $ echo -n $TEXT | gmssl sm4_cfb -sbytes 1 -encrypt -key $KEY -iv $IV -out sm4_cfb8_ciphertext.bin\n"
|
||||||
|
" $ gmssl sm4_cfb -sbytes 1 -decrypt -key $KEY -iv $IV -in sm4_cfb8_ciphertext.bin\n"
|
||||||
|
"\n"
|
||||||
|
" $ echo -n $TEXT | gmssl sm4_cfb -sbytes 8 -encrypt -key $KEY -iv $IV -out sm4_cfb64_ciphertext.bin\n"
|
||||||
|
" $ gmssl sm4_cfb -sbytes 8 -decrypt -key $KEY -iv $IV -in sm4_cfb64_ciphertext.bin\n"
|
||||||
"\n";
|
"\n";
|
||||||
|
|
||||||
int sm4_cfb_main(int argc, char **argv)
|
int sm4_cfb_main(int argc, char **argv)
|
||||||
@@ -45,6 +52,7 @@ int sm4_cfb_main(int argc, char **argv)
|
|||||||
int ret = 1;
|
int ret = 1;
|
||||||
char *prog = argv[0];
|
char *prog = argv[0];
|
||||||
int enc = -1;
|
int enc = -1;
|
||||||
|
int sbytes = SM4_CFB_128;
|
||||||
char *keyhex = NULL;
|
char *keyhex = NULL;
|
||||||
char *ivhex = NULL;
|
char *ivhex = NULL;
|
||||||
char *infile = NULL;
|
char *infile = NULL;
|
||||||
@@ -86,6 +94,14 @@ int sm4_cfb_main(int argc, char **argv)
|
|||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
enc = 0;
|
enc = 0;
|
||||||
|
} else if (!strcmp(*argv, "-sbytes")) {
|
||||||
|
if (--argc < 1) goto bad;
|
||||||
|
sbytes = atoi(*(++argv));
|
||||||
|
if (sbytes != SM4_CFB_8 && sbytes != SM4_CFB_64 && sbytes != SM4_CFB_128) {
|
||||||
|
fprintf(stderr, "%s: value of `-sbytes` should be %d, %d or %d\n", prog,
|
||||||
|
SM4_CFB_8, SM4_CFB_64, SM4_CFB_128);
|
||||||
|
goto end;
|
||||||
|
}
|
||||||
} else if (!strcmp(*argv, "-key")) {
|
} else if (!strcmp(*argv, "-key")) {
|
||||||
if (--argc < 1) goto bad;
|
if (--argc < 1) goto bad;
|
||||||
keyhex = *(++argv);
|
keyhex = *(++argv);
|
||||||
@@ -148,12 +164,12 @@ bad:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (enc) {
|
if (enc) {
|
||||||
if (sm4_cfb_encrypt_init(&ctx, 16, key, iv) != 1) {
|
if (sm4_cfb_encrypt_init(&ctx, sbytes, key, iv) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (sm4_cfb_decrypt_init(&ctx, 16, key, iv) != 1) {
|
if (sm4_cfb_decrypt_init(&ctx, sbytes, key, iv) != 1) {
|
||||||
error_print();
|
error_print();
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user