argon2 1.0.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
+
|