Skip to content

Commit

Permalink
Merge pull request #43 from InfoHunter/ascon-app
Browse files Browse the repository at this point in the history
Add ASCON command line tool
  • Loading branch information
dongbeiouba authored Oct 13, 2023
2 parents 32b3ffb + 20e52e5 commit 60e9f49
Showing 1 changed file with 270 additions and 0 deletions.
270 changes: 270 additions & 0 deletions app/minisuo.c
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <tongsuo/minisuo.h>
#include <tongsuo/sm3.h>
#include <tongsuo/sm4.h>
#include <tongsuo/ascon.h>
#include "internal/mem.h"

typedef int (*algorithm_handler)(int argc, char **argv);
Expand Down Expand Up @@ -211,12 +212,281 @@ static int sm3_handler(int argc, char **argv)
}
#endif

#ifdef TSM_HAVE_ASCON
static int ascon_aead_handler(int argc, char **argv)
{
int ret = 1, i, scheme, flags = 0, tag_set = 0;
long len;
int outlen;
size_t nread;
unsigned char inbuf[1024];
unsigned char outbuf[1024 + TSM_MAX_BLOCK_LENGTH];
void *ctx = NULL;
FILE *in = NULL, *out = NULL;
char *infile = NULL, *outfile = NULL;
unsigned char key[16];
unsigned char nonce[TSM_MAX_IV_LENGTH];
unsigned char tag[TSM_ASCON_AEAD_TAG_LEN];
/* associated data of ASCON is of arbitrary length. */
char *ad = NULL;

if (argc < 3) {
fprintf(stderr, "not adequate options\n");
return 1;
}

for (i = 2; i < argc; i++) {
if (strcmp(argv[i], "-scheme") == 0) {
i += 1;
if (i >= argc) {
fprintf(stderr, "no scheme argument\n");
return 1;
}
if (strcasecmp(argv[i], "128") == 0) {
scheme = TSM_ASCON_AEAD_128;
} else if (strcasecmp(argv[i], "128a") == 0) {
scheme = TSM_ASCON_AEAD_128A;
} else {
fprintf(stderr, "wrong scheme\n");
return 1;
}
} else if (strcmp(argv[i], "-key") == 0) {
i += 1;
if (i >= argc) {
fprintf(stderr, "no key\n");
return 1;
}
if (strlen(argv[i]) != 32) {
fprintf(stderr, "wrong key length\n");
return 1;
}

len = 16;
if (tsm_hex2bin(argv[i], key, &len) != TSM_OK || len != 16) {
fprintf(stderr, "wrong key format\n");
return 1;
}
} else if (strcmp(argv[i], "-nonce") == 0) {
i += 1;
if (i >= argc) {
fprintf(stderr, "no nonce\n");
return 1;
}
if (strlen(argv[i]) > sizeof(nonce) * 2) {
fprintf(stderr, "wrong nonce length\n");
return 1;
}

len = sizeof(nonce);
if (tsm_hex2bin(argv[i], nonce, &len) != TSM_OK) {
fprintf(stderr, "wrong iv format\n");
return 1;
}
} else if (strcmp(argv[i], "-ad") == 0) {
i += 1;
if (i >= argc) {
fprintf(stderr, "no associated data\n");
return 1;
}
ad = argv[i];
} else if (strcmp(argv[i], "-in") == 0) {
i += 1;
if (i >= argc) {
fprintf(stderr, "no input\n");
return 1;
}

infile = argv[i];
} else if (strcmp(argv[i], "-out") == 0) {
i += 1;
if (i >= argc) {
fprintf(stderr, "no output\n");
return 1;
}

outfile = argv[i];
} else if (strcmp(argv[i], "-enc") == 0) {
flags |= TSM_CIPH_FLAG_ENCRYPT;
} else if (strcmp(argv[i], "-dec") == 0) {
flags |= TSM_CIPH_FLAG_DECRYPT;
} else if (strcmp(argv[i], "-tag") == 0) {
i += 1;
if (i >= argc) {
fprintf(stderr, "no tag file\n");
return 1;
}
if (strlen(argv[i]) != 32) {
fprintf(stderr, "wrong tag length\n");
return 1;
}
len = TSM_ASCON_AEAD_TAG_LEN;
if (tsm_hex2bin(argv[i], tag, &len) != TSM_OK || len != 16) {
fprintf(stderr, "wrong tag format\n");
return 1;
}
tag_set = 1;
} else {
fprintf(stderr, "unknown option %s\n", argv[i]);
return 1;
}
}

if (flags == 0) {
fprintf(stderr, "either enc or dec should be specified\n");
return 1;
}

if (infile == NULL) {
in = stdin;
} else {
in = fopen(infile, "rb");
if (in == NULL) {
fprintf(stderr, "cannot open input file %s\n", infile);
return 1;
}
}

if (outfile == NULL) {
out = stdout;
} else {
out = fopen(outfile, "wb");
if (out == NULL) {
fprintf(stderr, "cannot open output file %s\n", outfile);
return 1;
}
}

ctx = tsm_ascon_aead_init(scheme, key, nonce, flags);
if (ctx == NULL)
return 1;

if (flags & TSM_CIPH_FLAG_DECRYPT) {
if (tag_set == 0) {
fprintf(stderr, "No tag set\n");
goto end;
}
if (tsm_ascon_aead_set_tag(ctx, tag) != TSM_OK) {
goto end;
}
}

if (ad != NULL && strlen(ad) > 0) {
if (tsm_ascon_aead_update(ctx, (unsigned char*)ad, strlen(ad), NULL, NULL) != TSM_OK) {
goto end;
}
}

while (1) {
nread = fread(inbuf, 1, sizeof(inbuf), in);
if (nread != sizeof(inbuf) && ferror(in)) {
fprintf(stderr, "read error\n");
goto end;
}

if (tsm_ascon_aead_update(ctx, inbuf, nread, outbuf, &outlen) != TSM_OK) {
fprintf(stderr, "cipher update error\n");
goto end;
}

if (fwrite(outbuf, 1, outlen, out) != (size_t)outlen) {
fprintf(stderr, "write error\n");
goto end;
}

if (feof(in))
break;
}

if (tsm_ascon_aead_final(ctx, outbuf, &outlen) != TSM_OK) {
fprintf(stderr, "cipher final error\n");
goto end;
}

if (fwrite(outbuf, 1, outlen, out) != (size_t)outlen) {
fprintf(stderr, "write error\n");
goto end;
}

/* tag is printed directly to stderr */
if (flags & TSM_CIPH_FLAG_ENCRYPT) {
if (tsm_ascon_aead_get_tag(ctx, tag) != TSM_OK) {
goto end;
}
fprintf(stderr, "TAG IS:\n");
for (i = 0; i < TSM_ASCON_AEAD_TAG_LEN; i++) {
fprintf(stderr, "%02X", tag[i]);
}
fprintf(stderr, "\n");
}

ret = 0;
end:
if (in != NULL && in != stdin)
fclose(in);
if (out != NULL && out != stdout)
fclose(out);
if (ctx != NULL)
tsm_ascon_aead_clean(ctx);
return ret;
}

static int ascon_hash_handler(int argc, char **argv)
{
unsigned char md[TSM_ASCON_HASH_LEN];
int i, md_len = 0, scheme;

if (argc == 3) {
/* it must be: minisuo ascon-hash -h */
if (strcmp(argv[2], "-h") == 0) {
fprintf(stderr, "minisuo ascon-hash -scheme HASH|HASHA -in DATA\n");
return 0;
}
}
if (argc == 6) {
if (strcmp(argv[2], "-scheme") != 0) {
fprintf(stderr, "wrong usage\n");
return 1;
}
if (strcmp(argv[4], "-in") != 0) {
fprintf(stderr, "wrong usage\n");
return 1;
}
if (strcasecmp(argv[3], "HASH") == 0) {
scheme = TSM_ASCON_HASH;
} else if (strcasecmp(argv[3], "HASHA") == 0) {
scheme = TSM_ASCON_HASHA;
} else {
fprintf(stderr, "wrong ASCON hash scheme\n");
return 1;
}
/* calculate ASCON hash, take argv[5] as the input */
if (tsm_ascon_hash_oneshot(scheme, (const unsigned char *)argv[5], strlen(argv[5]),
md, &md_len) != TSM_OK) {
fprintf(stderr, "calculation error\n");
return 1;
}
printf("ASCON Hash: ");
for (i = 0; i < TSM_ASCON_HASH_LEN; i++) {
printf("%02X", (unsigned int)md[i]);
}
printf("\n");
return 0;
}
fprintf(stderr, "wrong usage\n");
return 1;
}
#endif

static cmd_handler cmds[] = {
#ifdef TSM_HAVE_SM3
{"sm3", sm3_handler},
#endif
#ifdef TSM_HAVE_SM4
{"sm4", sm4_handler},
#endif
#ifdef TSM_HAVE_ASCON
{"ascon-aead", ascon_aead_handler},
{"ascon-hash", ascon_hash_handler},
#endif
{"\0", NULL}
};
Expand Down

0 comments on commit 60e9f49

Please sign in to comment.