argon2 1.0.0 → 1.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -1
- data/README.md +6 -5
- data/ext/argon2_wrap/argon_wrap.c +2 -1
- data/ext/argon2_wrap/test.c +5 -5
- data/ext/phc-winner-argon2/.gitattributes +5 -0
- data/ext/phc-winner-argon2/.gitignore +5 -0
- data/ext/phc-winner-argon2/Argon2.sln +98 -0
- data/ext/phc-winner-argon2/CHANGELOG.md +11 -0
- data/ext/phc-winner-argon2/Makefile +7 -2
- data/ext/phc-winner-argon2/README.md +27 -15
- data/ext/phc-winner-argon2/appveyor.yml +25 -0
- data/ext/phc-winner-argon2/export.sh +7 -0
- data/ext/phc-winner-argon2/include/argon2.h +24 -1
- data/ext/phc-winner-argon2/kats/argon2d +3 -1
- data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -1
- data/ext/phc-winner-argon2/kats/argon2d_v16 +12304 -0
- data/ext/phc-winner-argon2/kats/argon2d_v16.shasum +1 -0
- data/ext/phc-winner-argon2/kats/argon2i +3 -1
- data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -1
- data/ext/phc-winner-argon2/kats/argon2i_v16 +12304 -0
- data/ext/phc-winner-argon2/kats/argon2i_v16.shasum +1 -0
- data/ext/phc-winner-argon2/kats/check-sums.ps1 +42 -0
- data/ext/phc-winner-argon2/kats/check-sums.sh +1 -1
- data/ext/phc-winner-argon2/kats/test.ps1 +50 -0
- data/ext/phc-winner-argon2/kats/test.sh +45 -43
- data/ext/phc-winner-argon2/man/argon2.1 +47 -0
- data/ext/phc-winner-argon2/src/argon2.c +29 -15
- data/ext/phc-winner-argon2/src/bench.c +5 -22
- data/ext/phc-winner-argon2/src/core.c +3 -3
- data/ext/phc-winner-argon2/src/core.h +1 -3
- data/ext/phc-winner-argon2/src/encoding.c +22 -3
- data/ext/phc-winner-argon2/src/encoding.h +6 -0
- data/ext/phc-winner-argon2/src/genkat.c +23 -5
- data/ext/phc-winner-argon2/src/opt.c +42 -2
- data/ext/phc-winner-argon2/src/opt.h +10 -0
- data/ext/phc-winner-argon2/src/ref.c +51 -1
- data/ext/phc-winner-argon2/src/ref.h +10 -0
- data/ext/phc-winner-argon2/src/run.c +67 -42
- data/ext/phc-winner-argon2/src/test.c +160 -68
- data/ext/phc-winner-argon2/src/thread.c +1 -1
- data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +158 -0
- data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +158 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +167 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters +72 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +159 -0
- data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +158 -0
- data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +158 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters +69 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +159 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters +72 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +158 -0
- data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters +69 -0
- data/lib/argon2.rb +5 -1
- data/lib/argon2/version.rb +1 -1
- metadata +29 -3
@@ -229,7 +229,7 @@ static const char *decode_decimal(const char *str, unsigned long *v) {
|
|
229
229
|
*
|
230
230
|
* The code below applies the following format:
|
231
231
|
*
|
232
|
-
* $argon2<T
|
232
|
+
* $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>[,keyid=<bin>][,data=<bin>][$<bin>[$<bin>]]
|
233
233
|
*
|
234
234
|
* where <T> is either 'd' or 'i', <num> is a decimal integer (positive, fits in
|
235
235
|
* an 'unsigned long'), and <bin> is Base64-encoded data (no '=' padding
|
@@ -303,6 +303,9 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
|
303
303
|
CC("$argon2d");
|
304
304
|
else
|
305
305
|
return ARGON2_INCORRECT_TYPE;
|
306
|
+
ctx->version = ARGON2_VERSION_10;
|
307
|
+
/* Reading the version number if the default is suppressed */
|
308
|
+
CC_opt("$v=", DECIMAL(ctx->version));
|
306
309
|
CC("$m=");
|
307
310
|
DECIMAL(ctx->m_cost);
|
308
311
|
CC(",t=");
|
@@ -368,15 +371,17 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
368
371
|
} while ((void)0, 0)
|
369
372
|
|
370
373
|
if (type == Argon2_i)
|
371
|
-
SS("$argon2i$
|
374
|
+
SS("$argon2i$v=");
|
372
375
|
else if (type == Argon2_d)
|
373
|
-
SS("$argon2d$
|
376
|
+
SS("$argon2d$v=");
|
374
377
|
else
|
375
378
|
return ARGON2_ENCODING_FAIL;
|
376
379
|
|
377
380
|
if (validate_inputs(ctx) != ARGON2_OK) {
|
378
381
|
return validate_inputs(ctx);
|
379
382
|
}
|
383
|
+
SX(ctx->version);
|
384
|
+
SS("$m=");
|
380
385
|
SX(ctx->m_cost);
|
381
386
|
SS(",t=");
|
382
387
|
SX(ctx->t_cost);
|
@@ -405,3 +410,17 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
405
410
|
#undef SX
|
406
411
|
#undef SB
|
407
412
|
}
|
413
|
+
|
414
|
+
size_t b64len(uint32_t len) {
|
415
|
+
return (((size_t)len + 2) / 3) * 4;
|
416
|
+
}
|
417
|
+
|
418
|
+
size_t numlen(uint32_t num) {
|
419
|
+
size_t len = 1;
|
420
|
+
while (num >= 10) {
|
421
|
+
++len;
|
422
|
+
num = num / 10;
|
423
|
+
}
|
424
|
+
return len;
|
425
|
+
}
|
426
|
+
|
@@ -31,4 +31,10 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
31
31
|
*/
|
32
32
|
int decode_string(argon2_context *ctx, const char *str, argon2_type type);
|
33
33
|
|
34
|
+
/* Returns the length of the encoded byte stream with length len */
|
35
|
+
size_t b64len(uint32_t len);
|
36
|
+
|
37
|
+
/* Returns the length of the encoded number num */
|
38
|
+
size_t numlen(uint32_t num);
|
39
|
+
|
34
40
|
#endif
|
@@ -23,21 +23,24 @@ void initial_kat(const uint8_t *blockhash, const argon2_context *context,
|
|
23
23
|
unsigned i;
|
24
24
|
|
25
25
|
if (blockhash != NULL && context != NULL) {
|
26
|
-
printf("
|
26
|
+
printf("=======================================\n");
|
27
27
|
|
28
28
|
switch (type) {
|
29
29
|
case Argon2_d:
|
30
|
-
printf("Argon2d\n");
|
30
|
+
printf("Argon2d version number %d\n", context->version);
|
31
31
|
break;
|
32
32
|
|
33
33
|
case Argon2_i:
|
34
|
-
printf("Argon2i\n");
|
34
|
+
printf("Argon2i version number %d\n", context->version);
|
35
35
|
break;
|
36
36
|
|
37
37
|
default:
|
38
38
|
break;
|
39
39
|
}
|
40
40
|
|
41
|
+
printf("=======================================\n");
|
42
|
+
|
43
|
+
|
41
44
|
printf("Memory: %u KiB, Iterations: %u, Parallelism: %u lanes, Tag "
|
42
45
|
"length: %u bytes\n",
|
43
46
|
context->m_cost, context->t_cost, context->lanes,
|
@@ -130,7 +133,7 @@ static void fatal(const char *error) {
|
|
130
133
|
exit(1);
|
131
134
|
}
|
132
135
|
|
133
|
-
static void generate_testvectors(const char *type) {
|
136
|
+
static void generate_testvectors(const char *type, const uint32_t version) {
|
134
137
|
#define TEST_OUTLEN 32
|
135
138
|
#define TEST_PWDLEN 32
|
136
139
|
#define TEST_SALTLEN 16
|
@@ -157,6 +160,7 @@ static void generate_testvectors(const char *type) {
|
|
157
160
|
|
158
161
|
context.out = out;
|
159
162
|
context.outlen = TEST_OUTLEN;
|
163
|
+
context.version = ARGON2_VERSION_NUMBER;
|
160
164
|
context.pwd = pwd;
|
161
165
|
context.pwdlen = TEST_PWDLEN;
|
162
166
|
context.salt = salt;
|
@@ -173,6 +177,12 @@ static void generate_testvectors(const char *type) {
|
|
173
177
|
context.free_cbk = myown_deallocator;
|
174
178
|
context.flags = 0;
|
175
179
|
|
180
|
+
if(ARGON2_VERSION_10 == version || ARGON2_VERSION_NUMBER == version) {
|
181
|
+
context.version = version;
|
182
|
+
} else {
|
183
|
+
fatal("wrong Argon2 version number");
|
184
|
+
}
|
185
|
+
|
176
186
|
#undef TEST_OUTLEN
|
177
187
|
#undef TEST_PWDLEN
|
178
188
|
#undef TEST_SALTLEN
|
@@ -188,7 +198,15 @@ static void generate_testvectors(const char *type) {
|
|
188
198
|
}
|
189
199
|
|
190
200
|
int main(int argc, char *argv[]) {
|
201
|
+
/* Argon2 type */
|
191
202
|
const char *type = (argc > 1) ? argv[1] : "i";
|
192
|
-
|
203
|
+
|
204
|
+
/* Argon2 version number */
|
205
|
+
uint32_t version = ARGON2_VERSION_NUMBER;
|
206
|
+
if(argc > 2) {
|
207
|
+
version = strtoul(argv[2], NULL, 10);
|
208
|
+
}
|
209
|
+
|
210
|
+
generate_testvectors(type, version);
|
193
211
|
return ARGON2_OK;
|
194
212
|
}
|
@@ -21,7 +21,35 @@
|
|
21
21
|
#include "blake2/blake2.h"
|
22
22
|
#include "blake2/blamka-round-opt.h"
|
23
23
|
|
24
|
-
void
|
24
|
+
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
25
|
+
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
26
|
+
uint32_t i;
|
27
|
+
|
28
|
+
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
29
|
+
block_XY[i] = state[i] = _mm_xor_si128(
|
30
|
+
state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
|
31
|
+
}
|
32
|
+
|
33
|
+
for (i = 0; i < 8; ++i) {
|
34
|
+
BLAKE2_ROUND(state[8 * i + 0], state[8 * i + 1], state[8 * i + 2],
|
35
|
+
state[8 * i + 3], state[8 * i + 4], state[8 * i + 5],
|
36
|
+
state[8 * i + 6], state[8 * i + 7]);
|
37
|
+
}
|
38
|
+
|
39
|
+
for (i = 0; i < 8; ++i) {
|
40
|
+
BLAKE2_ROUND(state[8 * 0 + i], state[8 * 1 + i], state[8 * 2 + i],
|
41
|
+
state[8 * 3 + i], state[8 * 4 + i], state[8 * 5 + i],
|
42
|
+
state[8 * 6 + i], state[8 * 7 + i]);
|
43
|
+
}
|
44
|
+
|
45
|
+
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
46
|
+
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
47
|
+
_mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
|
48
|
+
}
|
49
|
+
}
|
50
|
+
|
51
|
+
void fill_block_with_xor(__m128i *state, const uint8_t *ref_block,
|
52
|
+
uint8_t *next_block) {
|
25
53
|
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
26
54
|
uint32_t i;
|
27
55
|
|
@@ -173,7 +201,19 @@ void fill_segment(const argon2_instance_t *instance,
|
|
173
201
|
ref_block =
|
174
202
|
instance->memory + instance->lane_length * ref_lane + ref_index;
|
175
203
|
curr_block = instance->memory + curr_offset;
|
176
|
-
|
204
|
+
if (ARGON2_VERSION_10 == instance->version) {
|
205
|
+
/* version 1.2.1 and earlier: overwrite, not XOR */
|
206
|
+
fill_block(state, (uint8_t *)ref_block->v,
|
207
|
+
(uint8_t *)curr_block->v);
|
208
|
+
} else {
|
209
|
+
if(0 == position.pass) {
|
210
|
+
fill_block(state, (uint8_t *)ref_block->v,
|
211
|
+
(uint8_t *)curr_block->v);
|
212
|
+
} else {
|
213
|
+
fill_block_with_xor(state, (uint8_t *)ref_block->v,
|
214
|
+
(uint8_t *)curr_block->v);
|
215
|
+
}
|
216
|
+
}
|
177
217
|
}
|
178
218
|
|
179
219
|
free(pseudo_rands);
|
@@ -27,6 +27,16 @@
|
|
27
27
|
*/
|
28
28
|
void fill_block_with_xor(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
|
29
29
|
|
30
|
+
/* LEGACY CODE: version 1.2.1 and earlier
|
31
|
+
* Function fills a new memory block by overwriting @next_block.
|
32
|
+
* @param state Pointer to the just produced block. Content will be updated(!)
|
33
|
+
* @param ref_block Pointer to the reference block
|
34
|
+
* @param next_block Pointer to the block to be XORed over. May coincide with @ref_block
|
35
|
+
* @pre all block pointers must be valid
|
36
|
+
*/
|
37
|
+
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block);
|
38
|
+
|
39
|
+
|
30
40
|
/*
|
31
41
|
* Generate pseudo-random values to reference blocks in the segment and puts
|
32
42
|
* them into the array
|
@@ -22,6 +22,45 @@
|
|
22
22
|
#include "blake2/blake2-impl.h"
|
23
23
|
#include "blake2/blake2.h"
|
24
24
|
|
25
|
+
|
26
|
+
void fill_block(const block *prev_block, const block *ref_block,
|
27
|
+
block *next_block) {
|
28
|
+
block blockR, block_tmp;
|
29
|
+
unsigned i;
|
30
|
+
|
31
|
+
copy_block(&blockR, ref_block);
|
32
|
+
xor_block(&blockR, prev_block);
|
33
|
+
copy_block(&block_tmp, &blockR);
|
34
|
+
/*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block */
|
35
|
+
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
|
36
|
+
(16,17,..31)... finally (112,113,...127) */
|
37
|
+
for (i = 0; i < 8; ++i) {
|
38
|
+
BLAKE2_ROUND_NOMSG(
|
39
|
+
blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
|
40
|
+
blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
|
41
|
+
blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
|
42
|
+
blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
|
43
|
+
blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
|
44
|
+
blockR.v[16 * i + 15]);
|
45
|
+
}
|
46
|
+
|
47
|
+
/* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
|
48
|
+
(2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
|
49
|
+
for (i = 0; i < 8; i++) {
|
50
|
+
BLAKE2_ROUND_NOMSG(
|
51
|
+
blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
|
52
|
+
blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
|
53
|
+
blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
|
54
|
+
blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
|
55
|
+
blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
|
56
|
+
blockR.v[2 * i + 113]);
|
57
|
+
}
|
58
|
+
|
59
|
+
copy_block(next_block, &block_tmp);
|
60
|
+
xor_block(next_block, &blockR);
|
61
|
+
}
|
62
|
+
|
63
|
+
|
25
64
|
void fill_block_with_xor(const block *prev_block, const block *ref_block,
|
26
65
|
block *next_block) {
|
27
66
|
block blockR, block_tmp;
|
@@ -171,7 +210,18 @@ void fill_segment(const argon2_instance_t *instance,
|
|
171
210
|
ref_block =
|
172
211
|
instance->memory + instance->lane_length * ref_lane + ref_index;
|
173
212
|
curr_block = instance->memory + curr_offset;
|
174
|
-
|
213
|
+
if (ARGON2_VERSION_10 == instance->version) {
|
214
|
+
/* version 1.2.1 and earlier: overwrite, not XOR */
|
215
|
+
fill_block(instance->memory + prev_offset, ref_block, curr_block);
|
216
|
+
} else {
|
217
|
+
if(0 == position.pass) {
|
218
|
+
fill_block(instance->memory + prev_offset, ref_block,
|
219
|
+
curr_block);
|
220
|
+
} else {
|
221
|
+
fill_block_with_xor(instance->memory + prev_offset, ref_block,
|
222
|
+
curr_block);
|
223
|
+
}
|
224
|
+
}
|
175
225
|
}
|
176
226
|
|
177
227
|
free(pseudo_rands);
|
@@ -26,6 +26,16 @@
|
|
26
26
|
void fill_block_with_xor(const block *prev_block, const block *ref_block,
|
27
27
|
block *next_block);
|
28
28
|
|
29
|
+
/* LEGACY CODE: version 1.2.1 and earlier
|
30
|
+
* Function fills a new memory block by overwriting @next_block.
|
31
|
+
* @param prev_block Pointer to the previous block
|
32
|
+
* @param ref_block Pointer to the reference block
|
33
|
+
* @param next_block Pointer to the block to be constructed
|
34
|
+
* @pre all block pointers must be valid
|
35
|
+
*/
|
36
|
+
void fill_block(const block *prev_block, const block *ref_block,
|
37
|
+
block *next_block);
|
38
|
+
|
29
39
|
/*
|
30
40
|
* Generate pseudo-random values to reference blocks in the segment and puts
|
31
41
|
* them into the array
|
@@ -28,12 +28,13 @@
|
|
28
28
|
#define LANES_DEF 1
|
29
29
|
#define THREADS_DEF 1
|
30
30
|
#define OUTLEN_DEF 32
|
31
|
+
#define MAX_PASS_LEN 128
|
31
32
|
|
32
33
|
#define UNUSED_PARAMETER(x) (void)(x)
|
33
34
|
|
34
35
|
static void usage(const char *cmd) {
|
35
36
|
printf("Usage: %s salt [-d] [-t iterations] [-m memory] "
|
36
|
-
"[-p parallelism] [-h hash length]\n",
|
37
|
+
"[-p parallelism] [-h hash length] [-e|-r]\n",
|
37
38
|
cmd);
|
38
39
|
printf("\tPassword is read from stdin\n");
|
39
40
|
printf("Parameters:\n");
|
@@ -47,6 +48,8 @@ static void usage(const char *cmd) {
|
|
47
48
|
THREADS_DEF);
|
48
49
|
printf("\t-h N\t\tSets hash output length to N bytes (default %d)\n",
|
49
50
|
OUTLEN_DEF);
|
51
|
+
printf("\t-e\t\tOutput only encoded hash\n");
|
52
|
+
printf("\t-r\t\tOutput only the raw bytes of the hash\n");
|
50
53
|
}
|
51
54
|
|
52
55
|
static void fatal(const char *error) {
|
@@ -54,26 +57,14 @@ static void fatal(const char *error) {
|
|
54
57
|
exit(1);
|
55
58
|
}
|
56
59
|
|
57
|
-
static
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
static uint32_t numlen(uint32_t num) {
|
62
|
-
uint32_t len = 1;
|
63
|
-
while (num >= 10) {
|
64
|
-
++len;
|
65
|
-
num = num / 10;
|
60
|
+
static void print_hex(uint8_t *bytes, size_t bytes_len) {
|
61
|
+
size_t i;
|
62
|
+
for (i = 0; i < bytes_len; ++i) {
|
63
|
+
printf("%02x", bytes[i]);
|
66
64
|
}
|
67
|
-
|
68
|
-
}
|
69
|
-
|
70
|
-
static uint32_t enclen(uint32_t outlen, uint32_t saltlen, uint32_t t_cost,
|
71
|
-
uint32_t m_cost, uint32_t lanes) {
|
72
|
-
return strlen("$argon2x$m=,t=,p=$$") + numlen(t_cost) + numlen(m_cost)
|
73
|
-
+ numlen(lanes) + b64len(saltlen) + b64len(outlen);
|
65
|
+
printf("\n");
|
74
66
|
}
|
75
67
|
|
76
|
-
|
77
68
|
/*
|
78
69
|
Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the
|
79
70
|
Base64-encoded hash string
|
@@ -84,14 +75,15 @@ Base64-encoded hash string
|
|
84
75
|
@m_cost amount of requested memory in KB
|
85
76
|
@lanes amount of requested parallelism
|
86
77
|
@threads actual parallelism
|
87
|
-
@type String, only "d" and "i" are
|
78
|
+
@type String, only "d" and "i" are acceptedi
|
79
|
+
@encoded_only display only the encoded hash
|
80
|
+
@raw_only display only the hexadecimal of the hash
|
88
81
|
*/
|
89
82
|
static void run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost,
|
90
83
|
uint32_t m_cost, uint32_t lanes, uint32_t threads,
|
91
|
-
argon2_type type) {
|
84
|
+
argon2_type type, int encoded_only, int raw_only) {
|
92
85
|
clock_t start_time, stop_time;
|
93
86
|
size_t pwdlen, saltlen, encodedlen;
|
94
|
-
uint32_t i;
|
95
87
|
int result;
|
96
88
|
|
97
89
|
start_time = clock();
|
@@ -116,7 +108,7 @@ static void run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost,
|
|
116
108
|
fatal("could not allocate memory for output");
|
117
109
|
}
|
118
110
|
|
119
|
-
encodedlen =
|
111
|
+
encodedlen = argon2_encodedlen(t_cost, m_cost, lanes, saltlen, outlen);
|
120
112
|
char* encoded = malloc(encodedlen + 1);
|
121
113
|
if (!encoded) {
|
122
114
|
secure_wipe_memory(pwd, strlen(pwd));
|
@@ -124,18 +116,29 @@ static void run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost,
|
|
124
116
|
}
|
125
117
|
|
126
118
|
result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen,
|
127
|
-
out, outlen, encoded, encodedlen, type
|
119
|
+
out, outlen, encoded, encodedlen, type,
|
120
|
+
ARGON2_VERSION_NUMBER);
|
128
121
|
if (result != ARGON2_OK)
|
129
122
|
fatal(argon2_error_message(result));
|
130
123
|
|
131
124
|
stop_time = clock();
|
132
125
|
|
133
|
-
|
134
|
-
|
135
|
-
|
126
|
+
if (encoded_only)
|
127
|
+
puts(encoded);
|
128
|
+
|
129
|
+
if (raw_only)
|
130
|
+
print_hex(out, outlen);
|
131
|
+
|
132
|
+
if (encoded_only || raw_only) {
|
133
|
+
free(out);
|
134
|
+
free(encoded);
|
135
|
+
return;
|
136
136
|
}
|
137
|
+
|
138
|
+
printf("Hash:\t\t");
|
139
|
+
print_hex(out, outlen);
|
137
140
|
free(out);
|
138
|
-
|
141
|
+
|
139
142
|
printf("Encoded:\t%s\n", encoded);
|
140
143
|
|
141
144
|
printf("%2.3f seconds\n",
|
@@ -155,23 +158,32 @@ int main(int argc, char *argv[]) {
|
|
155
158
|
uint32_t lanes = LANES_DEF;
|
156
159
|
uint32_t threads = THREADS_DEF;
|
157
160
|
argon2_type type = Argon2_i;
|
161
|
+
int encoded_only = 0;
|
162
|
+
int raw_only = 0;
|
158
163
|
int i;
|
159
164
|
size_t n;
|
160
|
-
char pwd[
|
165
|
+
char pwd[MAX_PASS_LEN], *salt;
|
161
166
|
|
162
167
|
if (argc < 2) {
|
163
168
|
usage(argv[0]);
|
164
169
|
return ARGON2_MISSING_ARGS;
|
165
170
|
}
|
166
171
|
|
167
|
-
salt = argv[1];
|
168
|
-
|
169
172
|
/* get password from stdin */
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
pwd[n - 1] = '\0';
|
173
|
+
n = fread(pwd, 1, sizeof pwd - 1, stdin);
|
174
|
+
if(n < 1) {
|
175
|
+
fatal("no password read");
|
174
176
|
}
|
177
|
+
if(n == MAX_PASS_LEN-1) {
|
178
|
+
fatal("Provided password longer than supported in command line utility");
|
179
|
+
}
|
180
|
+
|
181
|
+
pwd[n] = '\0';
|
182
|
+
if (pwd[n - 1] == '\n') {
|
183
|
+
pwd[n - 1] = '\0';
|
184
|
+
}
|
185
|
+
|
186
|
+
salt = argv[1];
|
175
187
|
|
176
188
|
/* parse options */
|
177
189
|
for (i = 2; i < argc; i++) {
|
@@ -231,19 +243,32 @@ int main(int argc, char *argv[]) {
|
|
231
243
|
}
|
232
244
|
} else if (!strcmp(a, "-d")) {
|
233
245
|
type = Argon2_d;
|
246
|
+
} else if (!strcmp(a, "-e")) {
|
247
|
+
encoded_only = 1;
|
248
|
+
} else if (!strcmp(a, "-r")) {
|
249
|
+
raw_only = 1;
|
234
250
|
} else {
|
235
251
|
fatal("unknown argument");
|
236
252
|
}
|
237
253
|
}
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
254
|
+
|
255
|
+
if(encoded_only && raw_only)
|
256
|
+
fatal("cannot provide both -e and -r");
|
257
|
+
|
258
|
+
if(!encoded_only && !raw_only) {
|
259
|
+
if (type == Argon2_i) {
|
260
|
+
printf("Type:\t\tArgon2i\n");
|
261
|
+
} else {
|
262
|
+
printf("Type:\t\tArgon2d\n");
|
263
|
+
}
|
264
|
+
printf("Iterations:\t%" PRIu32 " \n", t_cost);
|
265
|
+
printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost);
|
266
|
+
printf("Parallelism:\t%" PRIu32 " \n", lanes);
|
242
267
|
}
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
run(outlen, pwd, salt, t_cost, m_cost, lanes, threads, type);
|
268
|
+
|
269
|
+
run(outlen, pwd, salt, t_cost, m_cost, lanes, threads, type,
|
270
|
+
encoded_only, raw_only);
|
247
271
|
|
248
272
|
return ARGON2_OK;
|
249
273
|
}
|
274
|
+
|