2
0
Fork 0
mirror of https://git.sr.ht/~sircmpwn/mkproof synced 2024-06-03 11:36:12 +02:00
mkproof/src/run.c

283 lines
8.0 KiB
C
Raw Normal View History

2015-10-16 10:52:09 +02:00
/*
* Argon2 source code package
2015-10-16 19:05:50 +02:00
*
2015-10-16 10:52:09 +02:00
* Written by Daniel Dinu and Dmitry Khovratovich, 2015
2015-10-16 19:05:50 +02:00
*
2015-10-16 10:52:09 +02:00
* This work is licensed under a Creative Commons CC0 1.0 License/Waiver.
2015-10-16 19:05:50 +02:00
*
2015-10-20 22:46:17 +02:00
* You should have received a copy of the CC0 Public Domain Dedication along
* with
* this software. If not, see
* <http://creativecommons.org/publicdomain/zero/1.0/>.
2015-10-16 10:52:09 +02:00
*/
#define _GNU_SOURCE 1
2015-10-16 10:52:09 +02:00
#include <stdio.h>
#include <stdint.h>
2015-10-26 13:08:47 +01:00
#include <inttypes.h>
2015-10-16 10:52:09 +02:00
#include <stdlib.h>
#include <string.h>
2015-10-19 10:07:13 +02:00
#include <time.h>
2015-10-16 10:52:09 +02:00
#include "argon2.h"
#include "core.h"
2015-10-21 13:00:22 +02:00
2015-10-16 16:07:06 +02:00
#define T_COST_DEF 3
2015-10-28 11:45:20 +01:00
#define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */
2015-10-31 21:09:00 +01:00
#define LANES_DEF 1
#define THREADS_DEF 1
2015-10-29 11:25:25 +01:00
#define OUT_LEN 32
#define SALT_LEN 16
/* Sample encode: $argon2i$m=65536,t=2,p=4$c29tZXNhbHQAAAAAAAAAAA$QWLzI4TY9HkL2ZTLc8g6SinwdhZewYrzz9zxCo0bkGY
* Maximumum lengths are defined as:
* strlen $argon2i$ = 9
* m=65536 with strlen (uint32_t)-1 = 10, so this total is 12
* ,t=2,p=4 If we consider each number to potentially reach four digits in future, this = 14
2015-11-08 14:54:41 +01:00
* $c29tZXNhbHQAAAAAAAAAAA Formula for this is (SALT_LEN * 4 + 3) / 3 + 1 = 23
* $QWLzI4TY9HkL2ZTLc8g6SinwdhZewYrzz9zxCo0bkGY per above formula, = 44
* + NULL byte
2015-11-08 14:54:41 +01:00
* 9 + 12 + 14 + 23 + 44 + 1 = 103
* Rounded to 4 byte boundary: 104
2015-11-08 12:46:06 +01:00
*
2015-11-08 14:54:41 +01:00
* WARNING: 104 is only for the parameters supported by this
2015-11-08 12:46:06 +01:00
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
2015-10-16 16:07:06 +02:00
2015-10-16 18:41:54 +02:00
#define UNUSED_PARAMETER(x) (void)(x)
2015-10-16 16:07:06 +02:00
static void usage(const char *cmd) {
2015-11-06 16:48:22 +01:00
printf("Usage: %s salt [-d] [-t iterations] [-m memory] "
"[-p parallelism]\n",
2015-10-30 08:00:42 +01:00
cmd);
2015-11-06 16:48:22 +01:00
printf("\tPassword is read from stdin\n");
2015-10-28 16:42:52 +01:00
printf("Parameters:\n");
printf("\tsalt\t\tThe salt to use, at most 16 characters\n");
printf("\t-d\t\tUse Argon2d instead of Argon2i (which is the default)\n");
2015-10-30 08:00:42 +01:00
printf("\t-t N\t\tSets the number of iterations to N (default = %d)\n",
T_COST_DEF);
printf("\t-m N\t\tSets the memory usage of 2^N KiB (default %d)\n",
LOG_M_COST_DEF);
printf("\t-p N\t\tSets parallelism to N threads (default %d)\n",
THREADS_DEF);
2015-10-16 20:13:31 +02:00
}
static void fatal(const char *error) {
fprintf(stderr, "Error: %s\n", error);
exit(1);
2015-10-16 20:13:31 +02:00
}
2015-10-21 12:54:59 +02:00
/*
Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the
Base64-encoded hash string
2015-10-21 12:54:59 +02:00
@out output array with at least 32 bytes allocated
@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
*/
static void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost,
2015-10-27 21:38:01 +01:00
uint32_t m_cost, uint32_t lanes, uint32_t threads,
2015-11-06 13:53:52 +01:00
argon2_type type) {
2015-10-26 10:16:13 +01:00
clock_t start_time, stop_time;
2015-11-16 03:18:00 +01:00
size_t pwdlen;
char encoded[ENCODED_LEN];
2015-11-03 10:52:28 +01:00
uint32_t i;
2015-11-06 13:53:52 +01:00
int result;
start_time = clock();
if (!pwd) {
2015-10-21 10:08:17 +02:00
fatal("password missing");
}
if (!salt) {
secure_wipe_memory(pwd, strlen(pwd));
fatal("salt missing");
}
2015-10-21 10:08:17 +02:00
pwdlen = strlen(pwd);
2015-11-07 16:10:33 +01:00
UNUSED_PARAMETER(lanes);
2015-11-06 13:53:52 +01:00
result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, SALT_LEN,
out, OUT_LEN, encoded, sizeof encoded, type);
if (result != ARGON2_OK)
fatal(error_message(result));
2015-10-26 10:16:13 +01:00
stop_time = clock();
2015-11-02 17:05:29 +01:00
printf("Hash:\t\t");
for (i = 0; i < OUT_LEN; ++i) {
printf("%02x", out[i]);
2015-11-02 17:05:29 +01:00
}
printf("\n");
printf("Encoded:\t%s\n", encoded);
2015-11-02 17:05:29 +01:00
2015-10-30 08:00:42 +01:00
printf("%2.3f seconds\n",
((double)stop_time - start_time) / (CLOCKS_PER_SEC));
2015-11-06 13:53:52 +01:00
result = argon2_verify(encoded, pwd, pwdlen, type);
if (result != ARGON2_OK)
fatal(error_message(result));
printf("Verification ok\n");
2015-10-16 10:52:09 +02:00
}
#define HASHLEN 32
#define SALTLEN 16
#define PWD "password"
int main(void)
{
char hash_i[HASHLEN * 100];
char hash_d[HASHLEN * 100];
uint8_t salt[SALTLEN];
memset(salt, 0x00, SALTLEN);
uint8_t *pwd = (uint8_t *)strdup(PWD);
uint32_t pwdlen = strlen((char *)pwd);
uint32_t t_cost = 2; /* 1-pass computation */
uint32_t m_cost = (1 << 16); /* 64 mebibytes memory usage */
uint32_t parallelism = 1; /* number of threads and lanes */
argon2i_hash_encoded(
t_cost, m_cost,
parallelism,
pwd, pwdlen,
salt, SALTLEN,
HASHLEN,
hash_i, HASHLEN * 100
);
argon2d_hash_encoded(
t_cost, m_cost,
parallelism,
pwd, pwdlen,
salt, SALTLEN,
HASHLEN,
hash_d, HASHLEN * 100
);
printf("hash_i: %s\n", hash_i);
printf("hash_d: %s\n\n", hash_d);
int rv;
rv = argon2i_verify(hash_i, "hello", 5);
printf("wrong pwd, correct type (both i): %d\n", rv);
rv = argon2d_verify(hash_d, "hello", 5);
printf("wrong pwd, correct type (both d): %d\n", rv);
rv = argon2i_verify(hash_d, "hello", 5);
printf("wrong pwd, wrong type (i/d): %d\n", rv);
rv = argon2d_verify(hash_i, "hello", 5);
printf("wrong pwd, wrong type (d/i): %d\n", rv);
if (rv == 0) {
return 1;
}
return 0;
}
int main2(int argc, char *argv[]) {
2015-10-29 11:25:25 +01:00
unsigned char out[OUT_LEN];
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;
2015-10-29 11:25:25 +01:00
uint8_t salt[SALT_LEN];
2015-11-06 13:53:52 +01:00
argon2_type type = Argon2_i;
int i;
size_t n;
2015-11-06 16:48:22 +01:00
char pwd[128];
2015-10-16 19:05:50 +02:00
2015-11-06 16:48:22 +01:00
if (argc < 2) {
usage(argv[0]);
2015-10-21 11:59:39 +02:00
return ARGON2_MISSING_ARGS;
}
2015-10-16 10:52:09 +02:00
2015-11-06 16:48:22 +01:00
/* get password from stdin */
2015-11-07 16:10:33 +01:00
while ((n = fread(pwd, 1, sizeof pwd - 1, stdin)) > 0) {
2015-11-06 16:48:22 +01:00
pwd[n] = '\0';
2015-11-07 16:10:33 +01:00
if (pwd[n - 1] == '\n')
pwd[n - 1] = '\0';
2015-11-06 16:48:22 +01:00
}
/* get salt from command line */
if (strlen(argv[1]) > SALT_LEN) {
2015-10-21 10:08:17 +02:00
fatal("salt too long");
2015-10-27 17:40:32 +01:00
}
2015-10-29 11:25:25 +01:00
memset(salt, 0x00, SALT_LEN); /* pad with null bytes */
2015-11-06 16:48:22 +01:00
memcpy(salt, argv[1], strlen(argv[1]));
/* parse options */
2015-11-06 16:48:22 +01:00
for (i = 2; i < argc; i++) {
2015-10-27 17:40:32 +01:00
const char *a = argv[i];
unsigned long input = 0;
if (!strcmp(a, "-m")) {
if (i < argc - 1) {
i++;
2015-10-27 17:40:32 +01:00
input = strtoul(argv[i], NULL, 10);
2015-10-27 21:38:01 +01:00
if (input == 0 || input == ULONG_MAX ||
input > ARGON2_MAX_MEMORY_BITS) {
2015-10-27 17:40:32 +01:00
fatal("bad numeric input for -m");
}
m_cost = ARGON2_MIN(UINT64_C(1) << input, UINT32_C(0xFFFFFFFF));
2015-10-27 21:38:01 +01:00
if (m_cost > ARGON2_MAX_MEMORY) {
2015-10-27 17:40:32 +01:00
fatal("m_cost overflow");
}
continue;
2015-10-27 17:40:32 +01:00
} else {
fatal("missing -m argument");
2015-10-27 17:40:32 +01:00
}
} else if (!strcmp(a, "-t")) {
if (i < argc - 1) {
i++;
2015-10-27 17:40:32 +01:00
input = strtoul(argv[i], NULL, 10);
2015-10-27 21:38:01 +01:00
if (input == 0 || input == ULONG_MAX ||
input > ARGON2_MAX_TIME) {
2015-10-27 17:40:32 +01:00
fatal("bad numeric input for -t");
}
t_cost = input;
continue;
2015-10-27 17:40:32 +01:00
} else {
fatal("missing -t argument");
2015-10-27 17:40:32 +01:00
}
} else if (!strcmp(a, "-p")) {
if (i < argc - 1) {
i++;
2015-10-27 17:40:32 +01:00
input = strtoul(argv[i], NULL, 10);
2015-10-27 21:38:01 +01:00
if (input == 0 || input == ULONG_MAX ||
input > ARGON2_MAX_THREADS || input > ARGON2_MAX_LANES) {
2015-10-27 17:40:32 +01:00
fatal("bad numeric input for -p");
}
threads = input;
lanes = threads;
continue;
2015-10-27 17:40:32 +01:00
} else {
fatal("missing -p argument");
2015-10-27 17:40:32 +01:00
}
2015-10-28 16:42:52 +01:00
} else if (!strcmp(a, "-d")) {
2015-11-06 13:53:52 +01:00
type = Argon2_d;
2015-10-27 17:40:32 +01:00
} else {
fatal("unknown argument");
2015-10-27 17:40:32 +01:00
}
}
2015-11-07 16:10:33 +01:00
if (type == Argon2_i) {
2015-11-06 13:53:52 +01:00
printf("Type:\t\tArgon2i\n");
2015-11-07 16:10:33 +01:00
} else {
2015-11-06 13:53:52 +01:00
printf("Type:\t\tArgon2d\n");
2015-11-07 16:10:33 +01:00
}
2015-10-27 21:38:01 +01:00
printf("Iterations:\t%" PRIu32 " \n", t_cost);
2015-10-30 08:55:53 +01:00
printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost);
2015-10-27 21:38:01 +01:00
printf("Parallelism:\t%" PRIu32 " \n", lanes);
2015-10-21 10:08:17 +02:00
run(out, pwd, salt, t_cost, m_cost, lanes, threads, type);
2015-10-21 11:59:39 +02:00
return ARGON2_OK;
2015-10-16 10:52:09 +02:00
}