From 2d3d4c7f1d76c147958d8173480738014bf65724 Mon Sep 17 00:00:00 2001 From: alipha Date: Fri, 19 Feb 2016 17:25:33 -0600 Subject: [PATCH] Add options for hash length and bare output to exe --- src/run.c | 102 +++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 77 insertions(+), 25 deletions(-) diff --git a/src/run.c b/src/run.c index 10111d9..a749894 100644 --- a/src/run.c +++ b/src/run.c @@ -27,7 +27,8 @@ #define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */ #define LANES_DEF 1 #define THREADS_DEF 1 -#define OUT_LEN 32 +#define OUT_LEN_DEF 32 +#define MAX_OUT_LEN 1024 #define SALT_LEN 16 /* Sample encode: $argon2i$m=65536,t=2,p=4$c29tZXNhbHQAAAAAAAAAAA$QWLzI4TY9HkL2ZTLc8g6SinwdhZewYrzz9zxCo0bkGY @@ -36,22 +37,23 @@ * m=65536 with strlen (uint32_t)-1 = 10, so this total is 12 * ,t=2,p=4 where each number could reach four digits in future, this = 14 * $c29tZXNhbHQAAAAAAAAAAA Formula for this is (SALT_LEN * 4 + 3) / 3 + 1 = 23 - * $QWLzI4TY9HkL2ZTLc8g6SinwdhZewYrzz9zxCo0bkGY per above formula, = 44 + * $QWLzI4TY9HkL2ZTLc8g6SinwdhZewYrzz9zxCo0bkGY per above formula with MAX_OUT_LEN, = 1366 * + NULL byte - * 9 + 12 + 14 + 23 + 44 + 1 = 103 - * Rounded to 4 byte boundary: 104 + * 9 + 12 + 14 + 23 + 1366 + 1 = 1425 + * Rounded to 4 byte boundary: 1428 * - * WARNING: 104 is only for the parameters supported by this + * WARNING: 1428 is only for the parameters supported by this command-line utility. You'll need a longer ENCODED_LEN to support longer salts and ouputs, as supported by the argon2 library */ -#define ENCODED_LEN 108 +#define ENCODED_LEN 1428 #define UNUSED_PARAMETER(x) (void)(x) static void usage(const char *cmd) { printf("Usage: %s salt [-d] [-t iterations] [-m memory] " - "[-p parallelism]\n", + "[-p parallelism]\n" + "\t\t[-h hash_length] [-e|-r]\n", cmd); printf("\tPassword is read from stdin\n"); printf("Parameters:\n"); @@ -63,6 +65,10 @@ static void usage(const char *cmd) { LOG_M_COST_DEF); printf("\t-p N\t\tSets parallelism to N threads (default %d)\n", THREADS_DEF); + printf("\t-h N\t\tSets hash output length to N bytes (default %d)\n", + OUT_LEN_DEF); + printf("\t-e\t\tOutput only encoded hash\n"); + printf("\t-r\t\tOutput only the raw bytes of the hash\n"); } static void fatal(const char *error) { @@ -70,10 +76,19 @@ static void fatal(const char *error) { exit(1); } +static void print_hex(uint8_t *bytes, size_t bytes_len) { + size_t i; + for (i = 0; i < bytes_len; ++i) { + printf("%02x", bytes[i]); + } + printf("\n"); +} + /* Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the Base64-encoded hash string -@out output array with at least 32 bytes allocated +@out output array with at least out_len bytes allocated +@out_len length of the output array @pwd NULL-terminated string, presumably from argv[] @salt salt array with at least SALTLEN_DEF bytes allocated @t_cost number of iterations @@ -81,14 +96,15 @@ Base64-encoded hash string @lanes amount of requested parallelism @threads actual parallelism @type String, only "d" and "i" are accepted +@encoded_only display only the encoded hash +@raw_only display only the hexadecimal of the hash */ -static void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost, +static void run(uint8_t *out, uint32_t out_len, char *pwd, uint8_t *salt, uint32_t t_cost, uint32_t m_cost, uint32_t lanes, uint32_t threads, - argon2_type type) { + argon2_type type, int encoded_only, int raw_only) { clock_t start_time, stop_time; size_t pwdlen; char encoded[ENCODED_LEN]; - uint32_t i; int result; start_time = clock(); @@ -107,36 +123,47 @@ static void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost, UNUSED_PARAMETER(lanes); result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, SALT_LEN, - out, OUT_LEN, encoded, sizeof encoded, type); + out, out_len, encoded, sizeof encoded, type); if (result != ARGON2_OK) fatal(argon2_error_message(result)); stop_time = clock(); - printf("Hash:\t\t"); - for (i = 0; i < OUT_LEN; ++i) { - printf("%02x", out[i]); + if (encoded_only) { + puts(encoded); + return; } - printf("\n"); + + if (raw_only) { + print_hex(out, out_len); + return; + } + + printf("Hash:\t\t"); + print_hex(out, out_len); printf("Encoded:\t%s\n", encoded); printf("%2.3f seconds\n", ((double)stop_time - start_time) / (CLOCKS_PER_SEC)); result = argon2_verify(encoded, pwd, pwdlen, type); + if (result != ARGON2_OK) fatal(argon2_error_message(result)); printf("Verification ok\n"); } int main(int argc, char *argv[]) { - unsigned char out[OUT_LEN]; + unsigned char out[MAX_OUT_LEN]; + uint32_t out_len = OUT_LEN_DEF; uint32_t m_cost = 1 << LOG_M_COST_DEF; uint32_t t_cost = T_COST_DEF; uint32_t lanes = LANES_DEF; uint32_t threads = THREADS_DEF; uint8_t salt[SALT_LEN]; argon2_type type = Argon2_i; + int encoded_only = 0; + int raw_only = 0; int i; size_t n; char pwd[128]; @@ -207,21 +234,46 @@ int main(int argc, char *argv[]) { } else { fatal("missing -p argument"); } + } else if (!strcmp(a, "-h")) { + if (i < argc - 1) { + i++; + input = strtoul(argv[i], NULL, 10); + if (input < ARGON2_MIN_OUTLEN || input == ULONG_MAX || + input > MAX_OUT_LEN) { + fatal("bad numeric input for -h"); + } + out_len = input; + continue; + } else { + fatal("missing -h argument"); + } } else if (!strcmp(a, "-d")) { type = Argon2_d; + } else if (!strcmp(a, "-e")) { + encoded_only = 1; + } else if (!strcmp(a, "-r")) { + raw_only = 1; } else { fatal("unknown argument"); } } - if (type == Argon2_i) { - printf("Type:\t\tArgon2i\n"); - } else { - printf("Type:\t\tArgon2d\n"); + + if(encoded_only && raw_only) + fatal("cannot provide both -e and -r"); + + if(!encoded_only && !raw_only) { + if (type == Argon2_i) { + printf("Type:\t\tArgon2i\n"); + } else { + printf("Type:\t\tArgon2d\n"); + } + printf("Iterations:\t%" PRIu32 " \n", t_cost); + printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost); + printf("Parallelism:\t%" PRIu32 " \n", lanes); } - printf("Iterations:\t%" PRIu32 " \n", t_cost); - printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost); - printf("Parallelism:\t%" PRIu32 " \n", lanes); - run(out, pwd, salt, t_cost, m_cost, lanes, threads, type); + + run(out, out_len, pwd, salt, t_cost, m_cost, lanes, threads, type, + encoded_only, raw_only); return ARGON2_OK; }