diff --git a/demos/pbkdf2demo.sh b/demos/pbkdf2demo.sh new file mode 100755 index 00000000..844faa70 --- /dev/null +++ b/demos/pbkdf2demo.sh @@ -0,0 +1,5 @@ +#!/bin/bash + + +gmssl pbkdf2 -pass 1234 -salt 1122334455667788 -iter 60000 -outlen 16 + diff --git a/demos/sm2demo.sh b/demos/sm2demo.sh new file mode 100755 index 00000000..efee77d8 --- /dev/null +++ b/demos/sm2demo.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +gmssl sm2keygen -pass 1234 -out sm2.pem -pubout sm2pub.pem + +echo hello | gmssl sm2sign -key sm2.pem -pass 1234 -out sm2.sig #-id 1234567812345678 +echo hello | gmssl sm2verify -pubkey sm2pub.pem -sig sm2.sig -id 1234567812345678 + +echo hello | gmssl sm2encrypt -pubkey sm2pub.pem -out sm2.der +gmssl sm2decrypt -key sm2.pem -pass 1234 -in sm2.der + diff --git a/demos/sm3demo.sh b/demos/sm3demo.sh new file mode 100755 index 00000000..de6e044b --- /dev/null +++ b/demos/sm3demo.sh @@ -0,0 +1,10 @@ +#!/bin/bash + +echo -n abc | gmssl sm3 + +gmssl sm2keygen -pass 1234 -out sm2.pem -pubout sm2pub.pem +echo -n abc | gmssl sm3 -pubkey sm2pub.pem -id 1234567812345678 + + +echo -n abc | gmssl sm3hmac -key 11223344556677881122334455667788 + diff --git a/demos/sm4demo.sh b/demos/sm4demo.sh new file mode 100755 index 00000000..baa5af84 --- /dev/null +++ b/demos/sm4demo.sh @@ -0,0 +1,12 @@ +#!/bin/bash + + +KEY=11223344556677881122334455667788 +IV=11223344556677881122334455667788 + +echo hello | gmssl sm4 -cbc -encrypt -key $KEY -iv $IV -out sm4.cbc +gmssl sm4 -cbc -decrypt -key $KEY -iv $IV -in sm4.cbc + +echo hello | gmssl sm4 -ctr -encrypt -key $KEY -iv $IV -out sm4.ctr +gmssl sm4 -ctr -decrypt -key $KEY -iv $IV -in sm4.ctr + diff --git a/demos/zucdemo.sh b/demos/zucdemo.sh new file mode 100755 index 00000000..777f6a00 --- /dev/null +++ b/demos/zucdemo.sh @@ -0,0 +1,10 @@ +#!/bin/bash + + +KEY=11223344556677881122334455667788 +IV=11223344556677881122334455667788 + +echo hello | gmssl zuc -key $KEY -iv $IV -out zuc.bin +gmssl zuc -key $KEY -iv $IV -in zuc.bin + + diff --git a/include/gmssl/pbkdf2.h b/include/gmssl/pbkdf2.h index 3ba25574..0daeb8eb 100644 --- a/include/gmssl/pbkdf2.h +++ b/include/gmssl/pbkdf2.h @@ -60,6 +60,16 @@ extern "C" { #endif +/* +PBKDF2 Public API + + PBKDF2_MIN_ITER + PBKDF2_DEFAULT_SALT_SIZE + PBKDF2_MAX_SALT_SIZE + + pbkdf2_hmac_sm3_genkey +*/ + #define PBKDF2_MIN_ITER 10000 #define PBKDF2_MAX_ITER (INT_MAX) diff --git a/include/gmssl/skf.h b/include/gmssl/skf.h index 5424f69b..1ccea9df 100644 --- a/include/gmssl/skf.h +++ b/include/gmssl/skf.h @@ -122,7 +122,7 @@ int skf_print_device_info(FILE *fp, int fmt, int ind, const char *devname); int skf_open_device(SKF_DEVICE *dev, const char *devname, const uint8_t authkey[16]); int skf_set_label(SKF_DEVICE *dev, const char *label); int skf_change_authkey(SKF_DEVICE *dev, const uint8_t authkey[16]); -int skf_close_deivce(SKF_DEVICE *dev);; +int skf_close_device(SKF_DEVICE *dev); int skf_list_apps(SKF_DEVICE *dev, int fmt, int ind, const char *label, FILE *fp); int skf_create_app(SKF_DEVICE *dev, const char *appname, const char *admin_pin, const char *user_pin); diff --git a/src/skf/skf.c b/src/skf/skf.c index 69ae7dd3..ed062df7 100644 --- a/src/skf/skf.c +++ b/src/skf/skf.c @@ -235,7 +235,7 @@ int skf_release_key(SKF_KEY *key) return 1; } -int skf_close_deivce(SKF_DEVICE *dev) +int skf_close_device(SKF_DEVICE *dev) { if (SKF_UnlockDev(dev->handle) != SAR_OK || SKF_DisConnectDev(dev->handle) != SAR_OK) { diff --git a/tools/pbkdf2.c b/tools/pbkdf2.c index bdeadc2f..63005695 100644 --- a/tools/pbkdf2.c +++ b/tools/pbkdf2.c @@ -47,26 +47,30 @@ */ #include +#include #include #include -#include +#include #include -#include +#include -static const char *options = "-salt hex -iter num [-pass str] -outlen num"; +static const char *options = "-pass str -salt hex -iter num -outlen num [-bin|-hex] [-out file]"; int pbkdf2_main(int argc, char **argv) { - int ret = -1; + int ret = 1; char *prog = argv[0]; + char *pass = NULL; char *salthex = NULL; uint8_t salt[PBKDF2_MAX_SALT_SIZE]; size_t saltlen; int iter = 0; - char *pass = NULL; int outlen = 0; + int bin = 0; + char *outfile = NULL; uint8_t outbuf[64]; + FILE *outfp = stdout; int i; argc--; @@ -79,77 +83,98 @@ int pbkdf2_main(int argc, char **argv) while (argc > 0) { if (!strcmp(*argv, "-help")) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-pass")) { + if (--argc < 1) goto bad; + pass = *(++argv); } else if (!strcmp(*argv, "-salt")) { if (--argc < 1) goto bad; salthex = *(++argv); + if (strlen(salthex) > sizeof(salt) * 2) { + fprintf(stderr, "%s: invalid salt length\n", prog); + goto end; + } + if (hex_to_bytes(salthex, strlen(salthex), salt, &saltlen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } } else if (!strcmp(*argv, "-iter")) { if (--argc < 1) goto bad; iter = atoi(*(++argv)); if (iter < PBKDF2_MIN_ITER || iter > INT_MAX) { - error_print(); - return 1; + fprintf(stderr, "%s: invalid '-iter' value\n", prog); + goto end; } - } else if (!strcmp(*argv, "-pass")) { - if (--argc < 1) goto bad; - pass = *(++argv); } else if (!strcmp(*argv, "-outlen")) { if (--argc < 1) goto bad; outlen = atoi(*(++argv)); if (outlen < 1 || outlen > sizeof(outbuf)) { - error_print(); - return 1; + fprintf(stderr, "%s: invalid outlen\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-hex")) { + bin = 0; + } else if (!strcmp(*argv, "-bin")) { + bin = 1; + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; + goto end; bad: - fprintf(stderr, "%s: invalid option argument\n", prog); - return 1; + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; argv++; } + if (!pass) { + fprintf(stderr, "%s: option '-pass' required\n", prog); + goto end; + } if (!salthex) { - error_print(); - return 1; + fprintf(stderr, "%s: option '-salt' required\n", prog); + goto end; } - if (strlen(salthex) > sizeof(salt) * 2) { - error_print(); - return 1; - } - if (hex_to_bytes(salthex, strlen(salthex), salt, &saltlen) != 1) { - error_print(); - return 1; - } - if (!iter) { - error_print(); - return 1; + fprintf(stderr, "%s: option '-iter' required\n", prog); + goto end; } if (!outlen) { - error_print(); - return 1; - } - - - if (!pass) { - error_print(); - return -1; + fprintf(stderr, "%s: option '-outlen' required\n", prog); + goto end; } if (pbkdf2_hmac_sm3_genkey(pass, strlen(pass), salt, saltlen, iter, outlen, outbuf) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } - for (i = 0; i < outlen; i++) { - printf("%02X", outbuf[i]); + + if (bin) { + if (fwrite(outbuf, 1, outlen, outfp) != outlen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } + } else { + for (i = 0; i < outlen; i++) { + fprintf(outfp, "%02x", outbuf[i]); + } + fprintf(outfp, "\n"); } - printf("\n"); + ret = 0; - - return 0; +end: + gmssl_secure_clear(outbuf, sizeof(outbuf)); + gmssl_secure_clear(salt, sizeof(salt)); + if (outfile && outfp) fclose(outfp); + return ret; } diff --git a/tools/rand.c b/tools/rand.c index 0332655a..fc4f5f24 100644 --- a/tools/rand.c +++ b/tools/rand.c @@ -47,22 +47,25 @@ */ #include +#include #include #include #include +#include #include -#include -static const char *options = "[-hex] [-rdrand] -outlen num"; +static const char *options = "[-hex] [-rdrand] -outlen num [-out file]"; int rand_main(int argc, char **argv) { - int ret = -1; + int ret = 1; char *prog = argv[0]; int hex = 0; int rdrand = 0; int outlen = 0; + char *outfile = NULL; + FILE *outfp = stdout; uint8_t buf[2048]; int i; @@ -76,25 +79,33 @@ int rand_main(int argc, char **argv) while (argc > 0) { if (!strcmp(*argv, "-help")) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 1; + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; } else if (!strcmp(*argv, "-hex")) { hex = 1; } else if (!strcmp(*argv, "-rdrand")) { - // rdrand = 1; // FIXME: CMakeList.txt should be updated to support this option + rdrand = 1; } else if (!strcmp(*argv, "-outlen")) { if (--argc < 1) goto bad; outlen = atoi(*(++argv)); if (outlen < 1 || outlen > INT_MAX) { - error_print(); - return 1; + fprintf(stderr, "%s: invalid outlen\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-out")) { + if (--argc < 1) goto bad; + outfile = *(++argv); + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; + goto end; bad: - fprintf(stderr, "%s: invalid option argument\n", prog); - return 1; + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; @@ -102,8 +113,8 @@ bad: } if (!outlen) { - error_print(); - return 1; + fprintf(stderr, "%s: option -outlen missing\n", prog); + goto end; } while (outlen) { @@ -112,32 +123,36 @@ bad: if (rdrand) { /* if (rdrand_bytes(buf, len) != 1) { - error_print(); - return 1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } */ } else { if (rand_bytes(buf, len) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } } if (hex) { int i; for (i = 0; i < len; i++) { - fprintf(stdout, "%02X", buf[i]); + fprintf(outfp, "%02X", buf[i]); } } else { - fwrite(buf, 1, len, stdout); + if (fwrite(buf, 1, len, outfp) != len) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } } - outlen -= len; } - if (hex) { - fprintf(stdout, "\n"); + fprintf(outfp, "\n"); } - - return 0; + ret = 0; +end: + gmssl_secure_clear(buf, sizeof(buf)); + if (outfile && outfp) fclose(outfp); + return ret; } diff --git a/tools/sdfutil.c b/tools/sdfutil.c index 3236c94e..a1b98eb9 100644 --- a/tools/sdfutil.c +++ b/tools/sdfutil.c @@ -48,12 +48,13 @@ #include +#include #include #include +#include #include #include #include -#include #define OP_NONE 0 @@ -63,7 +64,6 @@ #define OP_RAND 4 - static void print_usage(FILE *fp, const char *prog) { fprintf(fp, "usage:\n"); @@ -90,15 +90,18 @@ int sdfutil_main(int argc, char **argv) unsigned char buf[4096]; unsigned int ulen; int len; - SDF_DEVICE dev; SDF_KEY key; + int dev_opened = 0; + int key_opened = 0; + memset(&dev, 0, sizeof(dev)); + memset(&key, 0, sizeof(key)); argc--; argv++; + if (argc < 1) { -bad: print_usage(stderr, prog); return 1; } @@ -131,50 +134,43 @@ bad: } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { - break; + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; argv++; } - if (argc) { - fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); - return 1; - } - if (!lib) { - fprintf(stderr, "Option '-lib' required\n"); - goto bad; + fprintf(stderr, "%s: option '-lib' required\n", prog); + goto end; } if (sdf_load_library(lib, NULL) != 1) { - error_print(); + fprintf(stderr, "%s: load library failure\n", prog); goto end; } - if (infile) { - if (!(infp = fopen(infile, "rb"))) { - error_print(); - return -1; - } - } - - if (outfile) { - if (!(outfp = fopen(outfile, "wb"))) { - error_print(); - return -1; - } - } - if (sdf_open_device(&dev) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: open device failure\n", prog); + goto end; } + dev_opened = 1; switch (op) { case OP_DEVINFO: @@ -183,11 +179,18 @@ bad: case OP_EXPORTPUBKEY: if (keyindex < 0) { - error_print(); + fprintf(stderr, "%s: invalid key index\n", prog); + goto end; + } + if (sdf_load_sign_key(&dev, &key, keyindex, pass) != 1) { + fprintf(stderr, "%s: load sign key failed\n", prog); + goto end; + } + key_opened = 1; + if (sm2_public_key_info_to_pem(&(key.public_key), outfp) != 1) { + fprintf(stderr, "%s: output public key to PEM failed\n", prog); goto end; } - sdf_load_sign_key(&dev, &key, keyindex, pass); - sm2_public_key_info_to_pem(&(key.public_key), outfp); break; case OP_SIGN: @@ -197,7 +200,11 @@ bad: uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; size_t siglen; - sdf_load_sign_key(&dev, &key, keyindex, pass); + if (sdf_load_sign_key(&dev, &key, keyindex, pass) != 1) { + fprintf(stderr, "%s: load sign key failed\n", prog); + goto end; + } + key_opened = 1; sm3_init(&sm3_ctx); sm2_compute_z(dgst, &(key.public_key.public_key), id, strlen(id)); @@ -209,22 +216,39 @@ bad: sm3_finish(&sm3_ctx, dgst); if ((ret = sdf_sign(&key, dgst, sig, &siglen)) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(sig, 1, siglen, outfp) != siglen) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } } break; case OP_RAND: - sdf_rand_bytes(&dev, buf, len); - fwrite(buf, 1, len, outfp); + if (sdf_rand_bytes(&dev, buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(buf, 1, len, outfp) != len) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } break; default: - error_print(); - return -1; + fprintf(stderr, "%s: this should not happen\n", prog); + goto end; } + ret = 0; end: + gmssl_secure_clear(buf, sizeof(buf)); + if (key_opened) sdf_release_key(&key); + if (dev_opened) sdf_close_device(&dev); + if (lib) sdf_unload_library(); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); return ret; } diff --git a/tools/skfutil.c b/tools/skfutil.c index 3c302e84..3356c10d 100644 --- a/tools/skfutil.c +++ b/tools/skfutil.c @@ -48,13 +48,14 @@ #include +#include #include #include +#include #include #include #include #include -#include #define OP_NONE 0 @@ -99,12 +100,16 @@ int skfutil_main(int argc, char **argv) size_t authkeylen; SKF_DEVICE dev; SKF_KEY key; + int dev_opened = 0; + int key_opened = 0; + memset(&dev, 0, sizeof(dev)); + memset(&key, 0, sizeof(key)); argc--; argv++; + if (argc < 1) { -bad: print_usage(stderr, prog); return 1; } @@ -128,8 +133,8 @@ bad: if (--argc < 1) goto bad; authkeystr = *(++argv); if (strlen(authkeystr) != 32) { - error_print(); - return -1; + fprintf(stderr, "%s: invalid authkey length\n", prog); + goto end; } hex_to_bytes(authkeystr, strlen(authkeystr), authkey, &authkeylen); } else if (!strcmp(*argv, "-exportpubkey")) { @@ -154,55 +159,46 @@ bad: } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { - break; + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; argv++; } - if (argc) { - fprintf(stderr, "%s: invalid option '%s'\n", prog, *argv); - return 1; - } - if (!lib) { - fprintf(stderr, "Option '-lib' required\n"); - goto bad; + fprintf(stderr, "%s: option '-lib' required\n", prog); + goto end; } if (skf_load_library(lib, NULL) != 1) { - error_print(); + fprintf(stderr, "%s: load library failure\n", prog); goto end; } - if (infile) { - if (!(infp = fopen(infile, "rb"))) { - error_print(); - return -1; - } - } - - if (outfile) { - if (!(outfp = fopen(outfile, "wb"))) { - error_print(); - return -1; - } - } - if (!op) { - error_print(); - goto bad; + fprintf(stderr, "%s: option of (-devinfo|-exportpubkey|-sign|-rand) required\n", prog); + goto end; } - if (!devname) { - error_print(); - goto bad; + fprintf(stderr, "%s: option '-dev' required\n", prog); + goto end; } if (op == OP_DEVINFO) { skf_print_device_info(stdout, 0, 0, devname); @@ -211,33 +207,46 @@ bad: } if (skf_open_device(&dev, devname, authkey) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: open device failure\n", prog); + goto end; } + dev_opened = 1; if (op == OP_RAND) { - skf_rand_bytes(&dev, buf, len); - fwrite(buf, 1, len, outfp); + if (skf_rand_bytes(&dev, buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(buf, 1, len, outfp) != len) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } ret = 0; goto end; } if (!appname) { - error_print(); - goto bad; + fprintf(stderr, "%s: option '-app' required\n", prog); + goto end; } if (!container_name) { - error_print(); - goto bad; + fprintf(stderr, "%s: option '-container' required\n", prog); + goto end; } if (!pass) { - error_print(); - goto bad; + fprintf(stderr, "%s: option '-pass' required\n", prog); + goto end; } if (op == OP_EXPORTPUBKEY) { - skf_load_sign_key(&dev, appname, pass, container_name, &key); - sm2_public_key_info_to_pem(&(key.public_key), outfp); + if (skf_load_sign_key(&dev, appname, pass, container_name, &key) != 1) { + fprintf(stderr, "%s: load sign key failed\n", prog); + goto end; + } + if (sm2_public_key_info_to_pem(&(key.public_key), outfp) != 1) { + fprintf(stderr, "%s: output public key PEM failure\n", prog); + goto end; + } ret = 0; goto end; } @@ -248,7 +257,11 @@ bad: uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; size_t siglen; - skf_load_sign_key(&dev, appname, pass, container_name, &key); + if (skf_load_sign_key(&dev, appname, pass, container_name, &key) != 1) { + fprintf(stderr, "%s: load sign key failed\n", prog); + goto end; + } + key_opened = 1; sm3_init(&sm3_ctx); sm2_compute_z(dgst, &(key.public_key.public_key), id, strlen(id)); @@ -260,12 +273,23 @@ bad: sm3_finish(&sm3_ctx, dgst); if ((ret = skf_sign(&key, dgst, sig, &siglen)) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } ret = 0; + goto end; + + } else { + fprintf(stderr, "%s: this should not happen\n", prog); + goto end; } end: + gmssl_secure_clear(buf, sizeof(buf)); + if (key_opened) skf_release_key(&key); + if (dev_opened) skf_close_device(&dev); + if (lib) skf_unload_library(); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); return ret; } diff --git a/tools/sm2decrypt.c b/tools/sm2decrypt.c index 92f38b84..dc005172 100644 --- a/tools/sm2decrypt.c +++ b/tools/sm2decrypt.c @@ -47,23 +47,18 @@ */ #include +#include #include #include -#include +#include #include -#include -#include -#include -#ifndef WIN32 -#include -#include -#endif - +static const char *options = "-key pem -pass str [-in file] [-out file]"; int sm2decrypt_main(int argc, char **argv) { + int ret = 1; char *prog = argv[0]; char *keyfile = NULL; char *pass = NULL; @@ -80,32 +75,46 @@ int sm2decrypt_main(int argc, char **argv) argc--; argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc > 0) { - if (!strcmp(*argv, "-help")) { -help: - fprintf(stderr, "usage: %s -key pem [-pass password] [-in file] [-out file]\n", prog); - return 0; - + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; } else if (!strcmp(*argv, "-key")) { if (--argc < 1) goto bad; keyfile = *(++argv); - + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-pass")) { if (--argc < 1) goto bad; pass = *(++argv); - } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); - + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto help; + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; @@ -113,63 +122,36 @@ help: } if (!keyfile) { - error_print(); - return -1; + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; } - if (!(keyfp = fopen(keyfile, "r"))) { - error_print(); - return -1; - } - if (!pass) { -#ifndef WIN32 - pass = getpass("Encryption Password : "); -#else fprintf(stderr, "%s: '-pass' option required\n", prog); -#endif - } - - if (infile) { - if (!(infp = fopen(infile, "rb"))) { - error_print(); - return -1; - } - } - - if (outfile) { - if (!(outfp = fopen(outfile, "wb"))) { - error_print(); - return -1; - } + goto end; } if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { - error_puts("private key decryption failure"); - return -1; + fprintf(stderr, "%s: private key decryption failure", prog); + goto end; } if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { - error_print(); - return -1; + fprintf(stderr, "%s: read input failed : %s\n", prog, strerror(errno)); + goto end; } if (sm2_decrypt(&key, inbuf, inlen, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: decryption failure\n", prog); + goto end; } if (outlen != fwrite(outbuf, 1, outlen, outfp)) { - error_print(); - return -1; + fprintf(stderr, "%s: output plaintext failed : %s\n", prog, strerror(errno)); + goto end; } - - memset(&key, 0, sizeof(SM2_KEY)); - - // FIXME: 清空所有缓冲区 - if (infile) fclose(infp); - if (outfile) fclose(outfp); - return 0; - -bad: - fprintf(stderr, "%s: '%s' option value required\n", prog, *argv); - return -1; - + ret = 0; +end: + gmssl_secure_clear(&key, sizeof(key)); + if (keyfp) fclose(keyfp); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; } diff --git a/tools/sm2encrypt.c b/tools/sm2encrypt.c index 69e23363..8b504355 100644 --- a/tools/sm2encrypt.c +++ b/tools/sm2encrypt.c @@ -47,20 +47,18 @@ */ #include +#include #include #include -#include -#include #include -#include -#include #include -#include +static const char *options = "(-pubkey pem | -cert pem) [-in file] [-out file]"; + int sm2encrypt_main(int argc, char **argv) { - int ret; + int ret = 1; char *prog = argv[0]; char *pubkeyfile = NULL; char *certfile = NULL; @@ -73,99 +71,112 @@ int sm2encrypt_main(int argc, char **argv) uint8_t cert[1024]; size_t certlen; SM2_KEY key; - uint8_t inbuf[SM2_MAX_PLAINTEXT_SIZE]; + uint8_t inbuf[SM2_MAX_PLAINTEXT_SIZE + 1]; uint8_t outbuf[SM2_MAX_CIPHERTEXT_SIZE]; size_t inlen, outlen = sizeof(outbuf); argc--; argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc > 1) { if (!strcmp(*argv, "-help")) { -help: - fprintf(stderr, "usage: %s {-pubkey pem | -cert pem} [-in file] [-out file]\n", prog); - return -1; - + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; } else if (!strcmp(*argv, "-pubkey")) { + if (certfile) { + fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); + goto end; + } if (--argc < 1) goto bad; pubkeyfile = *(++argv); - + if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-cert")) { + if (pubkeyfile) { + fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); + goto end; + } if (--argc < 1) goto bad; certfile = *(++argv); - + if (!(certfp = fopen(certfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); - + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { - goto help; + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } + argc--; argv++; } + if (pubkeyfile) { - if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { - error_print(); - return -1; - } if (sm2_public_key_info_from_pem(&key, pubkeyfp) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: parse public key failed\n", prog); + goto end; } } else if (certfile) { - if (!(certfp = fopen(certfile, "r"))) { - error_print(); - return -1; - } - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) { - error_print(); - return -1; - } - if (x509_cert_get_subject_public_key(cert, certlen, &key) != 1) { - error_print(); - return -1; + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &key) != 1) { + fprintf(stderr, "%s: parse certificate failed\n", prog); + goto end; } } else { - fprintf(stderr, "%s: '-pubkey' or '-cert' required\n", prog); - goto help; + fprintf(stderr, "%s: '-pubkey' or '-cert' option required\n", prog); + goto end; } - if (infile) { - if (!(infp = fopen(infile, "rb"))) { - error_print(); - return -1; - } - } - if (outfile) { - if (!(outfp = fopen(outfile, "wb"))) { - error_print(); - return -1; - } - } - - if ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) <= 0) { - error_print(); - return -1; + fprintf(stderr, "%s: read input error : %s\n", prog, strerror(errno)); + goto end; } + if (inlen > SM2_MAX_PLAINTEXT_SIZE) { + fprintf(stderr, "%s: input long than SM2_MAX_PLAINTEXT_SIZE (%d)\n", prog, SM2_MAX_PLAINTEXT_SIZE); + goto end; + } + if (sm2_encrypt(&key, inbuf, inlen, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (outlen != fwrite(outbuf, 1, outlen, outfp)) { - error_print(); - return -1; + fprintf(stderr, "%s: output error : %s\n", prog, strerror(errno)); + goto end; } - return 0; + ret = 0; -bad: - fprintf(stderr, "%s: '%s' option value required\n", prog, *argv); - return -1; +end: + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + if (pubkeyfp) fclose(pubkeyfp); + if (certfp) fclose(certfp); + return ret; } diff --git a/tools/sm2keygen.c b/tools/sm2keygen.c index a48a175f..fb20e0f0 100644 --- a/tools/sm2keygen.c +++ b/tools/sm2keygen.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (c) 2021 - 2021 The GmSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -47,23 +47,20 @@ */ #include +#include #include #include +#include #include -#include -#include -#include -#ifndef WIN32 -#include -#include -#endif + +static const char *options = "-pass str [-out pem] [-pubout pem]"; int sm2keygen_main(int argc, char **argv) { + int ret = 1; char *prog = argv[0]; char *pass = NULL; - char passbuf[64] = {0}; char *outfile = NULL; char *puboutfile = NULL; FILE *outfp = stdout; @@ -73,82 +70,61 @@ int sm2keygen_main(int argc, char **argv) argc--; argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc > 0) { if (!strcmp(*argv, "-help")) { -help: - fprintf(stderr, "usage: %s [-pass passphrase] [-out pem] [-pubout pem]\n", prog); - return -1; - + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; } else if (!strcmp(*argv, "-pass")) { if (--argc < 1) goto bad; pass = *(++argv); - } else if (!strcmp(*argv, "-out")) { if (--argc < 1) goto bad; outfile = *(++argv); - + if (!(outfp = fopen(outfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-pubout")) { if (--argc < 1) goto bad; puboutfile = *(++argv); - + if (!(puboutfp = fopen(puboutfile, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto help; + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; argv++; } - if (!pass) { -#ifndef WIN32 - pass = getpass("Encryption Password : "); - strncpy(passbuf, pass, sizeof(passbuf)); - pass = getpass("Encryption Password (Again) : "); - if (strcmp(passbuf, pass) != 0) { - fprintf(stderr, "error: passwords not match\n"); - return -1; - } -#else fprintf(stderr, "%s: '-pass' option required\n", prog); - goto help; -#endif + goto end; } - if (outfile) { - if (!(outfp = fopen(outfile, "w"))) { - error_print(); - return -1; - } - } - if (puboutfile) { - if (!(puboutfp = fopen(puboutfile, "w"))) { - error_print(); - return -1; - } + if (sm2_key_generate(&key) != 1 + || sm2_private_key_info_encrypt_to_pem(&key, pass, outfp) != 1 + || sm2_public_key_info_to_pem(&key, puboutfp) != 1) { + fprintf(stderr, "%s: inner failure\n", prog); + goto end; } + ret = 0; - if (sm2_key_generate(&key) != 1) { - error_print(); - return -1; - } - - if (sm2_private_key_info_encrypt_to_pem(&key, pass, outfp) != 1) { - memset(&key, 0, sizeof(SM2_KEY)); - error_print(); - return -1; - } - if (sm2_public_key_info_to_pem(&key, puboutfp) != 1) { - memset(&key, 0, sizeof(SM2_KEY)); - error_print(); - return -1; - } - - memset(&key, 0, sizeof(SM2_KEY)); - return 0; - -bad: - fprintf(stderr, "%s: '%s' option value required\n", prog, *argv); - return -1; +end: + gmssl_secure_clear(&key, sizeof(key)); + if (outfile && outfp) fclose(outfp); + if (puboutfile && puboutfp) fclose(puboutfp); + return ret; } diff --git a/tools/sm2sign.c b/tools/sm2sign.c index c1d4a6fa..e426ddd6 100644 --- a/tools/sm2sign.c +++ b/tools/sm2sign.c @@ -47,25 +47,18 @@ */ #include +#include #include #include -#include #include -#include -#include -#include - -#ifndef WIN32 -#include -#include -#endif +#include -// echo data | sm2sign -id "Alice" -keyfile sm2.pem -// echo data | sm2verify -id "Alice" -keyfile sm2pub.pem -certfile a -cacertfile b +static const char *options = "-key pem -pass str [-id str] [-in file] [-out file]"; int sm2sign_main(int argc, char **argv) { + int ret = 1; char *prog = argv[0]; char *keyfile = NULL; char *pass = NULL; @@ -85,35 +78,49 @@ int sm2sign_main(int argc, char **argv) argc--; argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc > 0) { if (!strcmp(*argv, "-help")) { -help: - fprintf(stderr, "usage: %s -key pem [-pass password] [-id str] [-in file] [-out file]\n", prog); - return -1; - + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; } else if (!strcmp(*argv, "-key")) { if (--argc < 1) goto bad; keyfile = *(++argv); - + if (!(keyfp = fopen(keyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, keyfile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-pass")) { if (--argc < 1) goto bad; pass = *(++argv); - } else if (!strcmp(*argv, "-id")) { if (--argc < 1) goto bad; id = *(++argv); - } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); - + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto help; + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; @@ -121,56 +128,42 @@ help: } if (!keyfile) { - error_print(); - goto help; + fprintf(stderr, "%s: '-key' option required\n", prog); + goto end; } - if (!(keyfp = fopen(keyfile, "r"))) { - error_print(); - return -1; - } - if (!pass) { -#ifndef WIN32 - pass = getpass("Encryption Password : "); -#else fprintf(stderr, "%s: '-pass' option required\n", prog); -#endif + goto end; } - - if (infile) { - if (!(infp = fopen(infile, "rb"))) { - error_print(); - return -1; - } - } - - if (outfile) { - if (!(outfp = fopen(outfile, "wb"))) { - error_print(); - return -1; - } - } - if (sm2_private_key_info_decrypt_from_pem(&key, pass, keyfp) != 1) { - error_puts("private key decryption failure"); - return -1; + fprintf(stderr, "%s: private key decryption failure\n", prog); + goto end; } - sm2_sign_init(&sign_ctx, &key, id, strlen(id)); - + if (sm2_sign_init(&sign_ctx, &key, id, strlen(id)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - sm2_sign_update(&sign_ctx, buf, len); + if (sm2_sign_update(&sign_ctx, buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } } - sm2_sign_finish(&sign_ctx, sig, &siglen); - - fwrite(sig, 1, siglen, outfp); - - memset(&key, 0, sizeof(SM2_KEY)); - - - return 0; - -bad: - fprintf(stderr, "%s: '%s' option value required\n", prog, *argv); - return -1; + if (sm2_sign_finish(&sign_ctx, sig, &siglen) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + if (fwrite(sig, 1, siglen, outfp) != siglen) { + fprintf(stderr, "%s: output signature failed : %s\n", prog, strerror(errno)); + goto end; + } + ret = 0; +end: + gmssl_secure_clear(&key, sizeof(key)); + gmssl_secure_clear(&sign_ctx, sizeof(sign_ctx)); + if (keyfp) fclose(keyfp); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; } diff --git a/tools/sm2verify.c b/tools/sm2verify.c index e75755e0..d70c6923 100644 --- a/tools/sm2verify.c +++ b/tools/sm2verify.c @@ -47,22 +47,18 @@ */ #include +#include #include #include -#include -#include #include -#include -#include #include -#include -// sm2verify [-in file] {-pubkey pem | -cert pem} [-id str] -sig file +static const char *options = "(-pubkey pem | -cert pem) [-id str] [-in file] -sig file"; int sm2verify_main(int argc, char **argv) { - int ret; + int ret = 1; char *prog = argv[0]; char *id = SM2_DEFAULT_ID; char *pubkeyfile = NULL; @@ -81,108 +77,123 @@ int sm2verify_main(int argc, char **argv) ssize_t len; uint8_t sig[SM2_MAX_SIGNATURE_SIZE]; size_t siglen; - + int vr; argc--; argv++; - while (argc > 1) { - if (!strcmp(*argv, "-help")) { -help: - fprintf(stderr, "usage: %s {-pubkey pem | -cert pem} [-id str] [-in file] -sig file\n", prog); - return -1; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc > 0) { + if (!strcmp(*argv, "-help")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; } else if (!strcmp(*argv, "-pubkey")) { + if (certfile) { + fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); + goto end; + } if (--argc < 1) goto bad; pubkeyfile = *(++argv); - + if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-cert")) { + if (pubkeyfile) { + fprintf(stderr, "%s: options '-pubkey' '-cert' conflict\n", prog); + goto end; + } if (--argc < 1) goto bad; certfile = *(++argv); - + if (!(certfp = fopen(certfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, certfile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-id")) { if (--argc < 1) goto bad; id = *(++argv); - } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); - + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, infile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-sig")) { if (--argc < 1) goto bad; sigfile = *(++argv); + if (!(sigfp = fopen(sigfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, sigfile, strerror(errno)); + goto end; + } } else { - goto help; + fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; argv++; } + if (!sigfile) { + fprintf(stderr, "%s: '-sig' option required\n", prog); + goto end; + } + if ((siglen = fread(sig, 1, sizeof(sig), sigfp)) <= 0) { + fprintf(stderr, "%s: read signature error : %s\n", prog, strerror(errno)); + goto end; + } if (pubkeyfile) { - if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { - error_print(); - return -1; - } if (sm2_public_key_info_from_pem(&key, pubkeyfp) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: parse public key failed\n", prog); + goto end; } } else if (certfile) { - if (!(certfp = fopen(certfile, "r"))) { - error_print(); - return -1; - } - if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1) { - error_print(); - return -1; - } - if (x509_cert_get_subject_public_key(cert, certlen, &key) != 1) { - error_print(); - return -1; + if (x509_cert_from_pem(cert, &certlen, sizeof(cert), certfp) != 1 + || x509_cert_get_subject_public_key(cert, certlen, &key) != 1) { + fprintf(stderr, "%s: parse certificate failed\n", prog); + goto end; } } else { fprintf(stderr, "%s: '-pubkey' or '-cert' option required\n", prog); - goto help; + goto end; } - if (infile) { - if (!(infp = fopen(infile, "r"))) { - error_print(); - return -1; + + if (sm2_verify_init(&verify_ctx, &key, id, strlen(id)) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; + } + while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { + if (sm2_verify_update(&verify_ctx, buf, len) != 1) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; } } - - if (!sigfile) { - error_print(); - goto help; - } - if (!(sigfp = fopen(sigfile, "rb"))) { - error_print(); - return -1; - } - if ((siglen = fread(sig, 1, sizeof(sig), sigfp)) <= 0) { - error_print(); - return -1; + if ((vr = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { + fprintf(stderr, "%s: inner error\n", prog); + goto end; } - sm2_verify_init(&verify_ctx, &key, id, strlen(id)); - while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { - sm2_verify_update(&verify_ctx, buf, len); + fprintf(stdout, "verify : %s\n", vr == 1 ? "success" : "failure"); + if (vr == 1) { + ret = 0; } - if ((ret = sm2_verify_finish(&verify_ctx, sig, siglen)) < 0) { - error_print(); - return -1; - } - - fprintf(stdout, "verify : %s\n", ret == 1 ? "success" : "failure"); - return ret == 1 ? 0 : -1; - - -bad: - fprintf(stderr, "%s: '%s' option value required\n", prog, *argv); - return -1; +end: + if (infile && infp) fclose(infp); + if (pubkeyfp) fclose(pubkeyfp); + if (certfp) fclose(certfp); + if (sigfp) fclose(sigfp); + return ret; } diff --git a/tools/sm3.c b/tools/sm3.c index 674460ee..88946a35 100644 --- a/tools/sm3.c +++ b/tools/sm3.c @@ -47,6 +47,7 @@ */ #include +#include #include #include #include @@ -54,9 +55,7 @@ #include -static const char *options = "[-hex|-bin] [-pubkey pem [-id str]] [-in file]"; - - +static const char *options = "[-hex|-bin] [-pubkey pem [-id str]] [-in file] [-out file]"; int sm3_main(int argc, char **argv) { @@ -65,10 +64,11 @@ int sm3_main(int argc, char **argv) int bin = 0; char *pubkeyfile = NULL; char *infile = NULL; + char *outfile = NULL; char *id = NULL; FILE *pubkeyfp = NULL; FILE *infp = stdin; - + FILE *outfp = stdout; SM3_CTX sm3_ctx; uint8_t dgst[32]; uint8_t buf[4096]; @@ -80,9 +80,10 @@ int sm3_main(int argc, char **argv) while (argc > 0) { if (!strcmp(*argv, "-help")) { - fprintf(stderr, "usage: %s %s\n", prog, options); - fprintf(stderr, "usage: echo -n \"abc\" | %s\n", prog); - return 0; + printf("usage: %s %s\n", prog, options); + printf("usage: echo -n \"abc\" | %s\n", prog); + ret = 0; + goto end; } else if (!strcmp(*argv, "-hex")) { if (bin) { error_print(); @@ -94,17 +95,32 @@ int sm3_main(int argc, char **argv) } else if (!strcmp(*argv, "-pubkey")) { if (--argc < 1) goto bad; pubkeyfile = *(++argv); + if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, pubkeyfile, strerror(errno)); + goto end; + } } else if (!strcmp(*argv, "-id")) { if (--argc < 1) goto bad; id = *(++argv); } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "r"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); goto end; bad: - fprintf(stderr, "%s: '%s' option value required\n", prog, *argv); + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); goto end; } @@ -118,12 +134,8 @@ bad: SM2_KEY sm2_key; uint8_t z[32]; - if (!(pubkeyfp = fopen(pubkeyfile, "r"))) { - error_print(); - goto end; - } if (sm2_public_key_info_from_pem(&sm2_key, pubkeyfp) != 1) { - error_print(); + fprintf(stderr, "%s: parse public key failed\n", prog); goto end; } if (!id) { @@ -132,7 +144,6 @@ bad: sm2_compute_z(z, (SM2_POINT *)&sm2_key, id, strlen(id)); sm3_update(&sm3_ctx, z, sizeof(z)); - } else { if (id) { fprintf(stderr, "%s: option '-id' must be with '-pubkey'\n", prog); @@ -140,30 +151,26 @@ bad: } } - if (infile) { - if (!(infp = fopen(infile, "r"))) { - error_print(); - goto end; - } - } while ((len = fread(buf, 1, sizeof(buf), infp)) > 0) { sm3_update(&sm3_ctx, buf, len); } - sm3_finish(&sm3_ctx, dgst); if (bin) { - fwrite(dgst, 1, 32, stdout); + if (fwrite(dgst, 1, sizeof(dgst), outfp) != sizeof(dgst)) { + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; + } } else { for (i = 0; i < sizeof(dgst); i++) { - printf("%02x", dgst[i]); + fprintf(outfp, "%02x", dgst[i]); } - printf("\n"); + fprintf(outfp, "\n"); } - ret = 0; - end: - if (infile) fclose(infp); + if (pubkeyfp) fclose(pubkeyfp); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); return ret; } diff --git a/tools/sm3hmac.c b/tools/sm3hmac.c index 83037f57..09f98ef7 100644 --- a/tools/sm3hmac.c +++ b/tools/sm3hmac.c @@ -47,48 +47,82 @@ */ #include +#include #include #include -#include +#include #include -#include +#include +static const char *options = "-key hex [-in file] [-bin|-hex] [-out file]"; + int sm3hmac_main(int argc, char **argv) { - int ret = -1; + int ret = 1; char *prog = argv[0]; char *keyhex = NULL; + int bin = 0; char *infile = NULL; - uint8_t key[32]; + char *outfile = NULL; + uint8_t key[SM3_DIGEST_SIZE]; size_t keylen; - FILE *in = stdin; - SM3_HMAC_CTX ctx; - uint8_t dgst[32]; + FILE *infp = stdin; + FILE *outfp = stdout; uint8_t buf[4096]; size_t len; + SM3_HMAC_CTX ctx; + uint8_t mac[SM3_HMAC_SIZE]; size_t i; argc--; argv++; + if (argc < 1) { + fprintf(stderr, "usage: %s %s\n", prog, options); + return 1; + } + while (argc > 0) { if (!strcmp(*argv, "-help")) { -help: - fprintf(stderr, "usage: %s -keyhex hex [-in file]\n", prog); - return -1; - - } else if (!strcmp(*argv, "-keyhex")) { + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; + } else if (!strcmp(*argv, "-key")) { if (--argc < 1) goto bad; keyhex = *(++argv); - + if (strlen(keyhex) > sizeof(key) * 2) { + fprintf(stderr, "%s: key should be less than 64 digits (32 bytes)\n", prog); + goto end; + } + if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } + } else if (!strcmp(*argv, "-hex")) { + bin = 0; + } else if (!strcmp(*argv, "-bin")) { + bin = 1; } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); - + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - goto help; + goto end; +bad: + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; @@ -96,38 +130,32 @@ help: } if (!keyhex) { - fprintf(stderr, "%s: option '-keyhex' required\n", prog); - goto help; - } - if (strlen(keyhex) > sizeof(key) * 2) { - error_print(); - return -1; - } - if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: option '-key' required\n", prog); + goto end; } sm3_hmac_init(&ctx, key, keylen); - while ((len = fread(buf, 1, sizeof(buf), stdin)) > 0) { sm3_hmac_update(&ctx, buf, len); } - sm3_hmac_finish(&ctx, dgst); + sm3_hmac_finish(&ctx, mac); - for (i = 0; i < sizeof(dgst); i++) { - printf("%02x", dgst[i]); + if (bin) { + if (fwrite(mac, 1, sizeof(mac), outfp) != sizeof(mac)) { + fprintf(stderr, "%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"); } - if (infile) { - printf(" : %s", infile); - } - printf("\n"); - - memset(&ctx, 0, sizeof(ctx)); - memset(key, 0, sizeof(key)); - return 0; - -bad: - fprintf(stderr, "%s: '%s' option value required\n", prog, *argv); - return -1; + 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; } diff --git a/tools/sm4.c b/tools/sm4.c index 553a4f82..936b2545 100644 --- a/tools/sm4.c +++ b/tools/sm4.c @@ -47,11 +47,12 @@ */ #include +#include #include #include +#include #include #include -#include #define SM4_MODE_CBC 1 @@ -59,12 +60,12 @@ static const char *options = "{-cbc|-ctr} {-encrypt|-decrypt} -key hex -iv hex [-in file] [-out file]"; - int sm4_main(int argc, char **argv) { + int ret = 1; char *prog = argv[0]; - char *keystr = NULL; - char *ivstr = NULL; + char *keyhex = NULL; + char *ivhex = NULL; char *infile = NULL; char *outfile = NULL; uint8_t key[16]; @@ -82,24 +83,41 @@ int sm4_main(int argc, char **argv) uint8_t outbuf[4196]; size_t outlen; - if (argc < 2) { + argc--; + argv++; + + if (argc < 1) { fprintf(stderr, "usage: %s %s\n", prog, options); return 1; } - argc--; - argv++; - while (argc > 0) { if (!strcmp(*argv, "-help")) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 0; + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; } else if (!strcmp(*argv, "-key")) { if (--argc < 1) goto bad; - keystr = *(++argv); + keyhex = *(++argv); + if (strlen(keyhex) != sizeof(key) * 2) { + fprintf(stderr, "%s: invalid key length\n", prog); + goto end; + } + if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } } else if (!strcmp(*argv, "-iv")) { if (--argc < 1) goto bad; - ivstr = *(++argv); + ivhex = *(++argv); + if (strlen(ivhex) != sizeof(iv) * 2) { + fprintf(stderr, "%s: invalid IV length\n", prog); + goto end; + } + if (hex_to_bytes(ivhex, strlen(ivhex), iv, &ivlen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } } else if (!strcmp(*argv, "-encrypt")) { enc = 1; } else if (!strcmp(*argv, "-decrypt")) { @@ -113,15 +131,23 @@ int sm4_main(int argc, char **argv) } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; + goto end; bad: - fprintf(stderr, "%s: no option value\n", prog); - return 1; + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; @@ -130,132 +156,109 @@ bad: if (!mode) { fprintf(stderr, "%s: mode not assigned, -cbc or -ctr option required\n", prog); - return 1; + goto end; } - - if (!keystr) { - error_print(); - return -1; + if (!keyhex) { + fprintf(stderr, "%s: option '-key' missing\n", prog); + goto end; } - if (strlen(keystr) != 32) { - printf("keystr len = %zu\n", strlen(keystr)); - error_print(); - return -1; - } - if (hex_to_bytes(keystr, strlen(keystr), key, &keylen) != 1) { - error_print(); - return -1; - } - - if (!ivstr) { - error_print(); - return -1; - } - if (strlen(ivstr) != 32) { - error_print(); - return -1; - } - if (hex_to_bytes(ivstr, strlen(ivstr), iv, &ivlen) != 1) { - error_print(); - return -1; - } - - if (infile) { - if (!(infp = fopen(infile, "r"))) { - error_print(); - return -1; - } - } - if (outfile) { - if (!(outfp = fopen(outfile, "w"))) { - error_print(); - return -1; - } + if (!ivhex) { + fprintf(stderr, "%s: option '-iv' missing\n", prog); + goto end; } if (mode == SM4_MODE_CTR) { if (sm4_ctr_encrypt_init(&ctr_ctx, key, iv) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { if (sm4_ctr_encrypt_update(&ctr_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - error_print(); - return -1; + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } } if (sm4_ctr_encrypt_finish(&ctr_ctx, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - error_print(); - return -1; + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } - - return 0; + ret = 0; + goto end; } - if (enc < 0) { - error_print(); - return -1; + fprintf(stderr, "%s: option -encrypt or -decrypt should be set\n", prog); + goto end; } if (enc) { if (sm4_cbc_encrypt_init(&cbc_ctx, key, iv) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { if (sm4_cbc_encrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - error_print(); - return -1; + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } } if (sm4_cbc_encrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - error_print(); - return -1; + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } } else { if (sm4_cbc_decrypt_init(&cbc_ctx, key, iv) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { if (sm4_cbc_decrypt_update(&cbc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - error_print(); - return -1; + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } } if (sm4_cbc_decrypt_finish(&cbc_ctx, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - error_print(); - return -1; + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } } + ret = 0; - return 0; +end: + gmssl_secure_clear(&cbc_ctx, sizeof(cbc_ctx)); + gmssl_secure_clear(&ctr_ctx, sizeof(ctr_ctx)); + gmssl_secure_clear(key, sizeof(key)); + gmssl_secure_clear(iv, sizeof(iv)); + gmssl_secure_clear(inbuf, sizeof(inbuf)); + gmssl_secure_clear(outbuf, sizeof(outbuf)); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; } diff --git a/tools/zuc.c b/tools/zuc.c index c4396bd5..2d529aab 100644 --- a/tools/zuc.c +++ b/tools/zuc.c @@ -47,22 +47,22 @@ */ #include +#include #include #include +#include #include #include -#include - static const char *options = "-key hex -iv hex [-in file] [-out file]"; - int zuc_main(int argc, char **argv) { + int ret = 1; char *prog = argv[0]; - char *keystr = NULL; - char *ivstr = NULL; + char *keyhex = NULL; + char *ivhex = NULL; char *infile = NULL; char *outfile = NULL; uint8_t key[16]; @@ -77,104 +77,106 @@ int zuc_main(int argc, char **argv) uint8_t outbuf[4196]; size_t outlen; - if (argc < 2) { + argc--; + argv++; + + if (argc < 1) { fprintf(stderr, "usage: %s %s\n", prog, options); return 1; } - argc--; - argv++; - while (argc > 0) { if (!strcmp(*argv, "-help")) { - fprintf(stderr, "usage: %s %s\n", prog, options); - return 0; + printf("usage: %s %s\n", prog, options); + ret = 0; + goto end; } else if (!strcmp(*argv, "-key")) { if (--argc < 1) goto bad; - keystr = *(++argv); + keyhex = *(++argv); + if (strlen(keyhex) != sizeof(key) * 2) { + fprintf(stderr, "%s: invalid key length\n", prog); + goto end; + } + if (hex_to_bytes(keyhex, strlen(keyhex), key, &keylen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } } else if (!strcmp(*argv, "-iv")) { if (--argc < 1) goto bad; - ivstr = *(++argv); + ivhex = *(++argv); + if (strlen(ivhex) != sizeof(iv) * 2) { + fprintf(stderr, "%s: invalid IV length\n", prog); + goto end; + } + if (hex_to_bytes(ivhex, strlen(ivhex), iv, &ivlen) != 1) { + fprintf(stderr, "%s: invalid HEX digits\n", prog); + goto end; + } } else if (!strcmp(*argv, "-in")) { if (--argc < 1) goto bad; infile = *(++argv); + if (!(infp = fopen(infile, "r"))) { + fprintf(stderr, "%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, "w"))) { + fprintf(stderr, "%s: open '%s' failure : %s\n", prog, outfile, strerror(errno)); + goto end; + } } else { fprintf(stderr, "%s: illegal option '%s'\n", prog, *argv); - return 1; + goto end; bad: - fprintf(stderr, "%s: no option value\n", prog); - return 1; + fprintf(stderr, "%s: '%s' option value missing\n", prog, *argv); + goto end; } argc--; argv++; } - if (!keystr) { - error_print(); - return -1; + if (!keyhex) { + fprintf(stderr, "%s: option '-key' missing\n", prog); + goto end; } - if (strlen(keystr) != 32) { - printf("keystr len = %zu\n", strlen(keystr)); - error_print(); - return -1; - } - if (hex_to_bytes(keystr, strlen(keystr), key, &keylen) != 1) { - error_print(); - return -1; - } - - if (!ivstr) { - error_print(); - return -1; - } - if (strlen(ivstr) != 32) { - error_print(); - return -1; - } - if (hex_to_bytes(ivstr, strlen(ivstr), iv, &ivlen) != 1) { - error_print(); - return -1; - } - - if (infile) { - if (!(infp = fopen(infile, "r"))) { - error_print(); - return -1; - } - } - if (outfile) { - if (!(outfp = fopen(outfile, "w"))) { - error_print(); - return -1; - } + if (!ivhex) { + fprintf(stderr, "%s: option '-iv' missing\n", prog); + goto end; } if (zuc_encrypt_init(&zuc_ctx, key, iv) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } while ((inlen = fread(inbuf, 1, sizeof(inbuf), infp)) > 0) { if (zuc_encrypt_update(&zuc_ctx, inbuf, inlen, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - error_print(); - return -1; + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } } if (zuc_encrypt_finish(&zuc_ctx, outbuf, &outlen) != 1) { - error_print(); - return -1; + fprintf(stderr, "%s: inner error\n", prog); + goto end; } if (fwrite(outbuf, 1, outlen, outfp) != outlen) { - error_print(); - return -1; + fprintf(stderr, "%s: output failure : %s\n", prog, strerror(errno)); + goto end; } - - return 0; + ret = 0; +end: + gmssl_secure_clear(&zuc_ctx, sizeof(zuc_ctx)); + gmssl_secure_clear(key, sizeof(key)); + gmssl_secure_clear(iv, sizeof(iv)); + gmssl_secure_clear(inbuf, sizeof(inbuf)); + gmssl_secure_clear(outbuf, sizeof(outbuf)); + if (infile && infp) fclose(infp); + if (outfile && outfp) fclose(outfp); + return ret; }