mirror of
https://github.com/guanzhi/GmSSL.git
synced 2026-05-06 16:36:16 +08:00
Add sm4_ccm command
This commit is contained in:
@@ -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);
|
||||
@@ -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"
|
||||
@@ -213,6 +217,10 @@ 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);
|
||||
@@ -220,6 +228,8 @@ int main(int argc, char **argv)
|
||||
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")) {
|
||||
|
||||
201
tools/sm4_cbc_mac.c
Normal file
201
tools/sm4_cbc_mac.c
Normal file
@@ -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;
|
||||
}
|
||||
@@ -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 =
|
||||
@@ -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;
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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;
|
||||
@@ -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];
|
||||
@@ -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++;
|
||||
@@ -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;
|
||||
}
|
||||
@@ -263,9 +265,10 @@ bad:
|
||||
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;
|
||||
}
|
||||
@@ -282,6 +285,7 @@ bad:
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (fwrite(outbuf, 1, outlen, outfp) != outlen) {
|
||||
fprintf(stderr, "%s: fwrite error\n", prog);
|
||||
goto end;
|
||||
@@ -292,9 +296,10 @@ bad:
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -40,7 +40,7 @@ static const char *options =
|
||||
" $ IV=`gmssl rand -outlen 12 -hex`\n"
|
||||
" $ AAD=\"The AAD Data\"\n"
|
||||
" $ echo -n $TEXT | gmssl sm4_gcm -encrypt -key $KEY -iv $IV -aad $AAD -out sm4_gcm_ciphertext.bin\n"
|
||||
" $ gmssl sm4_gcm -decrypt -key $KEY -iv $IV -in sm4_gcm_ciphertext.bin\n"
|
||||
" $ gmssl sm4_gcm -decrypt -key $KEY -iv $IV -aad $AAD -in sm4_gcm_ciphertext.bin\n"
|
||||
"\n";
|
||||
|
||||
int sm4_gcm_main(int argc, char **argv)
|
||||
|
||||
Reference in New Issue
Block a user