Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add options for hash length and bare output to exe #109

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
102 changes: 77 additions & 25 deletions src/run.c
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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");
Expand All @@ -63,32 +65,46 @@ 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) {
fprintf(stderr, "Error: %s\n", 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
@m_cost amount of requested memory in KB
@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();
Expand All @@ -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];
Expand Down Expand Up @@ -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;
}