Skip to content

Commit

Permalink
Add sm4_ccm command
Browse files Browse the repository at this point in the history
  • Loading branch information
guanzhi committed May 14, 2024
1 parent f5ed971 commit 8fb8dd0
Show file tree
Hide file tree
Showing 5 changed files with 236 additions and 18 deletions.
2 changes: 2 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -345,6 +345,7 @@ if (ENABLE_SM4_CCM)
set(ENABLE_SM4_CBC_MAC ON)
add_definitions(-DENABLE_SM4_CCM)
list(APPEND src src/sm4_ccm.c)
list(APPEND tools tools/sm4_ccm.c)
list(APPEND tests sm4_ccm)
endif()

Expand Down Expand Up @@ -441,6 +442,7 @@ endif()
if (ENABLE_SM4_CBC_MAC)
message(STATUS "ENABLE_SM4_CBC_MAC is ON")
list(APPEND src src/sm4_cbc_mac.c)
list(APPEND tools tools/sm4_cbc_mac.c)
list(APPEND tests sm4_cbc_mac)
endif()

Expand Down
10 changes: 10 additions & 0 deletions tools/gmssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,11 @@ extern int sm4_cbc_main(int argc, char **argv);
extern int sm4_ctr_main(int argc, char **argv);
extern int sm4_cfb_main(int argc, char **argv);
extern int sm4_ofb_main(int argc, char **argv);
extern int sm4_ccm_main(int argc, char **argv);
extern int sm4_gcm_main(int argc, char **argv);
extern int sm4_cbc_sm3_hmac_main(int argc, char **argv);
extern int sm4_ctr_sm3_hmac_main(int argc, char **argv);
extern int sm4_cbc_mac_main(int argc, char **argv);
extern int zuc_main(int argc, char **argv);
extern int sm9setup_main(int argc, char **argv);
extern int sm9keygen_main(int argc, char **argv);
Expand Down Expand Up @@ -91,9 +93,11 @@ static const char *options =
" sm4_ctr Encrypt or decrypt with SM4 CTR\n"
" sm4_cfb Encrypt or decrypt with SM4 CFB\n"
" sm4_ofb Encrypt or decrypt with SM4 OFB\n"
" sm4_ccm Encrypt or decrypt with SM4 CCM\n"
" sm4_gcm Encrypt or decrypt with SM4 GCM\n"
" sm4_cbc_sm3_hmac Encrypt or decrypt with SM4 CBC with SM3-HMAC\n"
" sm4_ctr_sm3_hmac Encrypt or decrypt with SM4 CTR with SM3-HMAC\n"
" sm4_cbc_mac Generate SM4 CBC-MAC\n"
" zuc Encrypt or decrypt with ZUC\n"
" sm9setup Generate SM9 master secret\n"
" sm9keygen Generate SM9 private key\n"
Expand Down Expand Up @@ -213,13 +217,19 @@ int main(int argc, char **argv)
#if ENABLE_SM4_OFB
} else if (!strcmp(*argv, "sm4_ofb")) {
return sm4_ofb_main(argc, argv);
#endif
#if ENABLE_SM4_CCM
} else if (!strcmp(*argv, "sm4_ccm")) {
return sm4_ccm_main(argc, argv);
#endif
} else if (!strcmp(*argv, "sm4_gcm")) {
return sm4_gcm_main(argc, argv);
} else if (!strcmp(*argv, "sm4_cbc_sm3_hmac")) {
return sm4_cbc_sm3_hmac_main(argc, argv);
} else if (!strcmp(*argv, "sm4_ctr_sm3_hmac")) {
return sm4_ctr_sm3_hmac_main(argc, argv);
} else if (!strcmp(*argv, "sm4_cbc_mac")) {
return sm4_cbc_mac_main(argc, argv);
} else if (!strcmp(*argv, "zuc")) {
return zuc_main(argc, argv);
} else if (!strcmp(*argv, "sm9setup")) {
Expand Down
201 changes: 201 additions & 0 deletions tools/sm4_cbc_mac.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
/*
* Copyright 2014-2023 The GmSSL Project. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the License); you may
* not use this file except in compliance with the License.
*
* http://www.apache.org/licenses/LICENSE-2.0
*/


#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <string.h>
#include <gmssl/hex.h>
#include <gmssl/mem.h>
#include <gmssl/sm4_cbc_mac.h>


static const char *usage = "-key hex [-in file | -in_str str] [-bin|-hex] [-out file]";

static const char *help =
"Options\n"
"\n"
" -key hex Hex string of the MAC key, 16 bytes\n"
" -in_str str Input as text string\n"
" -in file | stdin Input file path\n"
" `-in_str` and `-in` should not be used together\n"
" If neither `-in` nor `-in_str` specified, read from stdin\n"
" -hex Output MAC-tag as hex string (by default)\n"
" -bin Output MAC-tag as binary\n"
" `-hex` and `-bin` should not be used together\n"
" -out file | stdout Output file path. If not specified, output to stdout\n"
"\n"
"Examples\n"
"\n"
" KEY_HEX=`gmssl rand -outlen 16 -hex`\n"
" gmssl sm4_cbc_mac -key $KEY_HEX -in_str abc\n"
"\n"
" gmssl sm4_cbc_mac -key $KEY_HEX -in_str abc -bin\n"
"\n"
" gmssl sm4_cbc_mac -key $KEY_HEX -in /path/to/file\n"
"\n"
" When reading from stdin, make sure the trailing newline character is removed\n"
"\n"
" Linux/Mac:\n"
" echo -n abc | gmssl sm4_cbc_mac -key $KEY_HEX\n"
"\n"
" Windows:\n"
" C:\\> echo |set/p=\"abc\" | gmssl sm4_cbc_mac -key 11223344556677881122334455667788\n"
"\n";

int sm4_cbc_mac_main(int argc, char **argv)
{
int ret = 1;
char *prog = argv[0];
char *keyhex = NULL;
int outformat = 0;
char *in_str = NULL;
char *infile = NULL;
char *outfile = NULL;
uint8_t key[16];
size_t keylen;
FILE *infp = stdin;
FILE *outfp = stdout;
SM4_CBC_MAC_CTX ctx;
uint8_t mac[16];
size_t i;

argc--;
argv++;

if (argc < 1) {
fprintf(stderr, "usage: gmssl %s %s\n", prog, usage);
return 1;
}

while (argc > 0) {
if (!strcmp(*argv, "-help")) {
printf("usage: gmssl %s %s\n", prog, usage);
printf("%s\n", help);
ret = 0;
goto end;
} else if (!strcmp(*argv, "-key")) {
if (--argc < 1) goto bad;
keyhex = *(++argv);
if (strlen(keyhex) > sizeof(key) * 2) {
fprintf(stderr, "gmssl %s: key should be 16 bytes\n", prog);
goto end;
}
if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) {
fprintf(stderr, "gmssl %s: invalid HEX digits\n", prog);
goto end;
}
} else if (!strcmp(*argv, "-hex")) {
if (outformat == 2) {
fprintf(stderr, "gmssl %s: `-hex` and `-bin` should not be used together\n", prog);
goto end;
}
outformat = 1;
} else if (!strcmp(*argv, "-bin")) {
if (outformat == 1) {
fprintf(stderr, "gmssl %s: `-hex` and `-bin` should not be used together\n", prog);
goto end;
}
outformat = 2;
} else if (!strcmp(*argv, "-in_str")) {
if (infile) {
fprintf(stderr, "gmssl %s: `-in` and `-in_str` should not be used together\n", prog);
goto end;
}
if (--argc < 1) goto bad;
in_str = *(++argv);
} else if (!strcmp(*argv, "-in")) {
if (--argc < 1) goto bad;
infile = *(++argv);
if (!(infp = fopen(infile, "rb"))) {
fprintf(stderr, "gmssl %s: open '%s' failure : %s\n", prog, infile, strerror(errno));
goto end;
}
} else if (!strcmp(*argv, "-out")) {
if (--argc < 1) goto bad;
outfile = *(++argv);
if (!(outfp = fopen(outfile, "wb"))) {
fprintf(stderr, "gmssl %s: open '%s' failure : %s\n", prog, outfile, strerror(errno));
goto end;
}
} else {
fprintf(stderr, "gmssl %s: illegal option '%s'\n", prog, *argv);
goto end;
bad:
fprintf(stderr, "gmssl %s: '%s' option value missing\n", prog, *argv);
goto end;
}

argc--;
argv++;
}

if (!keyhex) {
fprintf(stderr, "gmssl %s: option '-key' required\n", prog);
goto end;
}

sm4_cbc_mac_init(&ctx, key);
/*
if (sm4_cbc_mac_init(&ctx, key) != 1) {
fprintf(stderr, "gmssl %s: inner error\n", prog);
goto end;
}
*/

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) {
fprintf(stderr, "gmssl %s: inner error\n", prog);
goto end;
}
*/
} else {
uint8_t buf[4096];
size_t len;
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) {
fprintf(stderr, "gmssl %s: inner error\n", prog);
goto end;
}
*/
}
memset(buf, 0, sizeof(buf));
}
sm4_cbc_mac_finish(&ctx, mac);
/*
if (sm4_cbc_mac_finish(&ctx, mac) != 1) {
fprintf(stderr, "gmssl %s: inner error\n", prog);
goto end;
}
*/

if (outformat > 1) {
if (fwrite(mac, 1, sizeof(mac), outfp) != sizeof(mac)) {
fprintf(stderr, "gmssl %s: output failure : %s\n", prog, strerror(errno));
goto end;
}
} else {
for (i = 0; i < sizeof(mac); i++) {
fprintf(outfp, "%02x", mac[i]);
}
fprintf(outfp, "\n");
}
ret = 0;
end:
gmssl_secure_clear(key, sizeof(key));
gmssl_secure_clear(&ctx, sizeof(ctx));
if (infile && infp) fclose(infp);
if (outfile && outfp) fclose(outfp);
return ret;
}
39 changes: 22 additions & 17 deletions tools/sm4_ccm.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,6 @@
#include <gmssl/error.h>


// 这个要对照sm4.c中的再修改一下


static const char *usage = "{-encrypt|-decrypt} -key hex -iv hex [-aad str| -aad_hex hex] [-taglen num] [-in file] [-out file]";

static const char *options =
Expand All @@ -36,13 +33,16 @@ static const char *options =
" -in file | stdin Input data\n"
" -out file | stdout Output data\n"
"\n"
"Examples"
"Examples\n"
"\n"
" echo \"hello\" | gmssl sm4_ccm -encrypt -key 11223344556677881122334455667788 -iv 112233445566778811223344 -out ciphertext.bin\n"
" gmssl sm4_ccm -decrypt -key 11223344556677881122334455667788 -iv 112233445566778811223344 -in ciphertext.bin\n"
" $ TEXT=`gmssl rand -outlen 20 -hex`\n"
" $ KEY=`gmssl rand -outlen 16 -hex`\n"
" $ IV=`gmssl rand -outlen 12 -hex`\n"
" $ AAD=\"The AAD Data\"\n"
" $ echo -n $TEXT | gmssl sm4_ccm -encrypt -key $KEY -iv $IV -aad $AAD -out sm4_ccm_ciphertext.bin\n"
" $ gmssl sm4_ccm -decrypt -key $KEY -iv $IV -aad $AAD -in sm4_ccm_ciphertext.bin\n"
"\n";


static uint8_t *read_content(FILE *infp, size_t *outlen, const char *prog)
{
const size_t INITIAL_BUFFER_SIZE = 4096;
Expand All @@ -52,7 +52,7 @@ static uint8_t *read_content(FILE *infp, size_t *outlen, const char *prog)
size_t total_read = 0;

if (!(buffer = (uint8_t *)malloc(INITIAL_BUFFER_SIZE))) {
fprintf(stderr, "%s: malloc failure\n", prog);
fprintf(stderr, "gmssl %s: malloc failure\n", prog);
return NULL;
}

Expand All @@ -63,7 +63,7 @@ static uint8_t *read_content(FILE *infp, size_t *outlen, const char *prog)
uint8_t *new_buffer;

if (buffer_size >= MAX_BUFFER_SIZE) {
fprintf(stderr, "%s: input too long, should be less than %zu\n", prog, MAX_BUFFER_SIZE);
fprintf(stderr, "gmssl %s: input too long, should be less than %zu\n", prog, MAX_BUFFER_SIZE);
free(buffer);
return NULL;
}
Expand All @@ -73,7 +73,7 @@ static uint8_t *read_content(FILE *infp, size_t *outlen, const char *prog)
}

if (!(new_buffer = (uint8_t *)realloc(buffer, buffer_size))) {
fprintf(stderr, "%s: realloc failure\n", prog);
fprintf(stderr, "gmssl %s: realloc failure\n", prog);
free(buffer);
return NULL;
}
Expand All @@ -88,7 +88,7 @@ static uint8_t *read_content(FILE *infp, size_t *outlen, const char *prog)
}

if (ferror(infp)) {
fprintf(stderr, "%s: fread error\n", prog);
fprintf(stderr, "gmssl %s: fread error\n", prog);
perror("error reading input");
free(buffer);
return NULL;
Expand All @@ -110,7 +110,7 @@ int sm4_ccm_main(int argc, char **argv)
uint8_t *aad = NULL;
uint8_t *aad_buf = NULL;
size_t aadlen = 0;
int taglen = SM4_CCM_DEFAULT_MAC_SIZE;
int taglen = SM4_CCM_DEFAULT_TAG_SIZE;
char *infile = NULL;
char *outfile = NULL;
uint8_t key[16];
Expand All @@ -120,9 +120,11 @@ int sm4_ccm_main(int argc, char **argv)
FILE *infp = stdin;
FILE *outfp = stdout;
SM4_KEY sm4_key;
uint8_t buf[4096]; // CCM不是update 模式的,因此输出可能比输入长
uint8_t *inbuf = NULL;
size_t inlen;
uint8_t *outbuf = NULL;
size_t outlen;
uint8_t *tag;

argc--;
argv++;
Expand Down Expand Up @@ -203,7 +205,7 @@ int sm4_ccm_main(int argc, char **argv)
} else if (!strcmp(*argv, "-taglen")) {
if (--argc < 1) goto bad;
taglen = atoi(*(++argv));
if (taglen < SM4_CCM_MIN_MAC_SIZE || taglen > SM4_CCM_MAX_MAC_SIZE) {
if (taglen < SM4_CCM_MIN_TAG_SIZE || taglen > SM4_CCM_MAX_TAG_SIZE) {
fprintf(stderr, "%s: `-taglen` invalid integer argument\n", prog);
goto end;
}
Expand Down Expand Up @@ -263,9 +265,10 @@ int sm4_ccm_main(int argc, char **argv)
error_print();
goto end;
}

} else {
if (inlen < taglen) {
fprintf(stderr, "%s: input length (%zu bytes) shorter than tag length (%zu bytes)\n",
fprintf(stderr, "%s: input length (%zu bytes) shorter than tag length (%d bytes)\n",
prog, inlen, taglen);
goto end;
}
Expand All @@ -282,6 +285,7 @@ int sm4_ccm_main(int argc, char **argv)
}
}


if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
fprintf(stderr, "%s: fwrite error\n", prog);
goto end;
Expand All @@ -292,9 +296,10 @@ int sm4_ccm_main(int argc, char **argv)
end:
gmssl_secure_clear(key, sizeof(key));
gmssl_secure_clear(iv, sizeof(iv));
gmssl_secure_clear(&ctx, sizeof(ctx));
gmssl_secure_clear(buf, sizeof(buf));
gmssl_secure_clear(&sm4_key, sizeof(sm4_key));
if (infile && infp) fclose(infp);
if (outfile && outfp) fclose(outfp);
if (inbuf) free(inbuf);
if (outbuf) free(outbuf);
return ret;
}
Loading

0 comments on commit 8fb8dd0

Please sign in to comment.