argon2 0.1.1 → 0.1.2
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 -0
- data/README.md +23 -4
- data/ext/argon2_wrap/Makefile +2 -7
- data/ext/argon2_wrap/argon_wrap.c +3 -4
- data/ext/argon2_wrap/test.c +3 -3
- data/ext/phc-winner-argon2/.gitignore +3 -0
- data/ext/phc-winner-argon2/CHANGELOG.md +7 -0
- data/ext/phc-winner-argon2/Makefile +0 -6
- data/ext/phc-winner-argon2/README.md +8 -0
- data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
- data/ext/phc-winner-argon2/kats/argon2d +12291 -12291
- data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -1
- data/ext/phc-winner-argon2/kats/argon2i +12291 -12291
- data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -1
- data/ext/phc-winner-argon2/src/argon2.c +71 -0
- data/ext/phc-winner-argon2/src/argon2.h +17 -0
- data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +6 -5
- data/ext/phc-winner-argon2/src/core.c +8 -56
- data/ext/phc-winner-argon2/src/core.h +3 -10
- data/ext/phc-winner-argon2/src/encoding.c +9 -9
- data/ext/phc-winner-argon2/src/genkat.c +3 -3
- data/ext/phc-winner-argon2/src/opt.c +5 -7
- data/ext/phc-winner-argon2/src/opt.h +5 -0
- data/lib/argon2.rb +0 -4
- data/lib/argon2/ffi_engine.rb +8 -4
- data/lib/argon2/version.rb +1 -1
- metadata +4 -3
@@ -1 +1 @@
|
|
1
|
-
|
1
|
+
82ca18d6df38a67b1a52f610f19f1917e5b118014fe31995c83350b92319fa06 argon2i
|
@@ -105,6 +105,61 @@ static const char *Argon2_ErrorMessage[] = {
|
|
105
105
|
{ARGON2_DECODING_FAIL, */ "Decoding failed", /*},*/
|
106
106
|
};
|
107
107
|
|
108
|
+
|
109
|
+
int argon2_core(argon2_context *context, argon2_type type) {
|
110
|
+
/* 1. Validate all inputs */
|
111
|
+
int result = validate_inputs(context);
|
112
|
+
uint32_t memory_blocks, segment_length;
|
113
|
+
argon2_instance_t instance;
|
114
|
+
|
115
|
+
if (ARGON2_OK != result) {
|
116
|
+
return result;
|
117
|
+
}
|
118
|
+
|
119
|
+
if (Argon2_d != type && Argon2_i != type) {
|
120
|
+
return ARGON2_INCORRECT_TYPE;
|
121
|
+
}
|
122
|
+
|
123
|
+
/* 2. Align memory size */
|
124
|
+
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
|
125
|
+
memory_blocks = context->m_cost;
|
126
|
+
|
127
|
+
if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
|
128
|
+
memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
|
129
|
+
}
|
130
|
+
|
131
|
+
segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
|
132
|
+
/* Ensure that all segments have equal length */
|
133
|
+
memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
|
134
|
+
|
135
|
+
instance.memory = NULL;
|
136
|
+
instance.passes = context->t_cost;
|
137
|
+
instance.memory_blocks = memory_blocks;
|
138
|
+
instance.segment_length = segment_length;
|
139
|
+
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
|
140
|
+
instance.lanes = context->lanes;
|
141
|
+
instance.threads = context->threads;
|
142
|
+
instance.type = type;
|
143
|
+
|
144
|
+
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
145
|
+
* blocks
|
146
|
+
*/
|
147
|
+
result = initialize(&instance, context);
|
148
|
+
|
149
|
+
if (ARGON2_OK != result) {
|
150
|
+
return result;
|
151
|
+
}
|
152
|
+
|
153
|
+
/* 4. Filling memory */
|
154
|
+
fill_memory_blocks(&instance);
|
155
|
+
|
156
|
+
/* 5. Finalization */
|
157
|
+
finalize(context, &instance);
|
158
|
+
|
159
|
+
return ARGON2_OK;
|
160
|
+
}
|
161
|
+
|
162
|
+
|
108
163
|
int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
|
109
164
|
const uint32_t parallelism, const void *pwd,
|
110
165
|
const size_t pwdlen, const void *salt, const size_t saltlen,
|
@@ -311,6 +366,22 @@ int verify_d(argon2_context *context, const char *hash) {
|
|
311
366
|
return 0 == memcmp(hash, context->out, context->outlen);
|
312
367
|
}
|
313
368
|
|
369
|
+
int verify_i(argon2_context *context, const char *hash) {
|
370
|
+
int result;
|
371
|
+
if (0 == context->outlen || NULL == hash) {
|
372
|
+
return ARGON2_OUT_PTR_MISMATCH;
|
373
|
+
}
|
374
|
+
|
375
|
+
result = argon2_core(context, Argon2_i);
|
376
|
+
|
377
|
+
if (ARGON2_OK != result) {
|
378
|
+
return result;
|
379
|
+
}
|
380
|
+
|
381
|
+
return 0 == memcmp(hash, context->out, context->outlen);
|
382
|
+
}
|
383
|
+
|
384
|
+
|
314
385
|
const char *error_message(int error_code) {
|
315
386
|
enum {
|
316
387
|
/* Make sure---at compile time---that the enum size matches the array
|
@@ -194,6 +194,14 @@ typedef struct Argon2_Context {
|
|
194
194
|
/* Argon2 primitive type */
|
195
195
|
typedef enum Argon2_type { Argon2_d = 0, Argon2_i = 1 } argon2_type;
|
196
196
|
|
197
|
+
|
198
|
+
/*
|
199
|
+
* Function that performs memory-hard hashing with certain degree of parallelism
|
200
|
+
* @param context Pointer to the Argon2 internal structure
|
201
|
+
* @return Error code if smth is wrong, ARGON2_OK otherwise
|
202
|
+
*/
|
203
|
+
int argon2_core(argon2_context *context, argon2_type type);
|
204
|
+
|
197
205
|
/**
|
198
206
|
* Hashes a password with Argon2i, producing an encoded hash
|
199
207
|
* @param t_cost Number of iterations
|
@@ -319,6 +327,15 @@ int argon2id(argon2_context *context);
|
|
319
327
|
*/
|
320
328
|
int verify_d(argon2_context *context, const char *hash);
|
321
329
|
|
330
|
+
/*
|
331
|
+
* Verify if a given password is correct for Argon2i hashing
|
332
|
+
* @param context Pointer to current Argon2 context
|
333
|
+
* @param hash The password hash to verify. The length of the hash is
|
334
|
+
* specified by the context outlen member
|
335
|
+
* @return Zero if successful, a non zero error code otherwise
|
336
|
+
*/
|
337
|
+
int verify_i(argon2_context *context, const char *hash);
|
338
|
+
|
322
339
|
/*
|
323
340
|
* Get the associated error message for given error code
|
324
341
|
* @return The error message associated with the given error code
|
@@ -3,11 +3,11 @@
|
|
3
3
|
|
4
4
|
#include "blake2-impl.h"
|
5
5
|
|
6
|
-
#
|
7
|
-
#
|
6
|
+
#include <emmintrin.h>
|
7
|
+
#if defined(__SSSE3__)
|
8
|
+
#include <tmmintrin.h> /* for _mm_shuffle_epi8 and _mm_alignr_epi8 */
|
8
9
|
#endif
|
9
10
|
|
10
|
-
#include <immintrin.h>
|
11
11
|
#if defined(__XOP__) && (defined(__GNUC__) || defined(__clang__))
|
12
12
|
#include <x86intrin.h>
|
13
13
|
#endif
|
@@ -134,11 +134,12 @@ static BLAKE2_INLINE __m128i fBlaMka(__m128i x, __m128i y) {
|
|
134
134
|
|
135
135
|
#define UNDIAGONALIZE(A0, B0, C0, D0, A1, B1, C1, D1) \
|
136
136
|
do { \
|
137
|
-
__m128i t0
|
137
|
+
__m128i t0, t1; \
|
138
|
+
t0 = C0; \
|
138
139
|
C0 = C1; \
|
139
140
|
C1 = t0; \
|
140
141
|
t0 = B0; \
|
141
|
-
|
142
|
+
t1 = D0; \
|
142
143
|
B0 = _mm_unpackhi_epi64(B1, _mm_unpacklo_epi64(B0, B0)); \
|
143
144
|
B1 = _mm_unpackhi_epi64(t0, _mm_unpacklo_epi64(B1, B1)); \
|
144
145
|
D0 = _mm_unpackhi_epi64(D0, _mm_unpacklo_epi64(D1, D1)); \
|
@@ -54,26 +54,26 @@
|
|
54
54
|
void init_block_value(block *b, uint8_t in) { memset(b->v, in, sizeof(b->v)); }
|
55
55
|
|
56
56
|
void copy_block(block *dst, const block *src) {
|
57
|
-
memcpy(dst->v, src->v, sizeof(uint64_t) *
|
57
|
+
memcpy(dst->v, src->v, sizeof(uint64_t) * ARGON2_QWORDS_IN_BLOCK);
|
58
58
|
}
|
59
59
|
|
60
60
|
void xor_block(block *dst, const block *src) {
|
61
61
|
int i;
|
62
|
-
for (i = 0; i <
|
62
|
+
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
63
63
|
dst->v[i] ^= src->v[i];
|
64
64
|
}
|
65
65
|
}
|
66
66
|
|
67
67
|
static void load_block(block *dst, const void *input) {
|
68
68
|
unsigned i;
|
69
|
-
for (i = 0; i <
|
69
|
+
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
70
70
|
dst->v[i] = load64((const uint8_t *)input + i * sizeof(dst->v[i]));
|
71
71
|
}
|
72
72
|
}
|
73
73
|
|
74
74
|
static void store_block(void *output, const block *src) {
|
75
75
|
unsigned i;
|
76
|
-
for (i = 0; i <
|
76
|
+
for (i = 0; i < ARGON2_QWORDS_IN_BLOCK; ++i) {
|
77
77
|
store64((uint8_t *)output + i * sizeof(src->v[i]), src->v[i]);
|
78
78
|
}
|
79
79
|
}
|
@@ -424,6 +424,10 @@ int validate_inputs(const argon2_context *context) {
|
|
424
424
|
return ARGON2_MEMORY_TOO_MUCH;
|
425
425
|
}
|
426
426
|
|
427
|
+
if (context->m_cost < 8*context->lanes) {
|
428
|
+
return ARGON2_MEMORY_TOO_LITTLE;
|
429
|
+
}
|
430
|
+
|
427
431
|
/* Validate time cost */
|
428
432
|
if (ARGON2_MIN_TIME > context->t_cost) {
|
429
433
|
return ARGON2_TIME_TOO_SMALL;
|
@@ -606,55 +610,3 @@ int initialize(argon2_instance_t *instance, argon2_context *context) {
|
|
606
610
|
return ARGON2_OK;
|
607
611
|
}
|
608
612
|
|
609
|
-
int argon2_core(argon2_context *context, argon2_type type) {
|
610
|
-
/* 1. Validate all inputs */
|
611
|
-
int result = validate_inputs(context);
|
612
|
-
uint32_t memory_blocks, segment_length;
|
613
|
-
argon2_instance_t instance;
|
614
|
-
|
615
|
-
if (ARGON2_OK != result) {
|
616
|
-
return result;
|
617
|
-
}
|
618
|
-
|
619
|
-
if (Argon2_d != type && Argon2_i != type) {
|
620
|
-
return ARGON2_INCORRECT_TYPE;
|
621
|
-
}
|
622
|
-
|
623
|
-
/* 2. Align memory size */
|
624
|
-
/* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
|
625
|
-
memory_blocks = context->m_cost;
|
626
|
-
|
627
|
-
if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
|
628
|
-
memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
|
629
|
-
}
|
630
|
-
|
631
|
-
segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
|
632
|
-
/* Ensure that all segments have equal length */
|
633
|
-
memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
|
634
|
-
|
635
|
-
instance.memory = NULL;
|
636
|
-
instance.passes = context->t_cost;
|
637
|
-
instance.memory_blocks = memory_blocks;
|
638
|
-
instance.segment_length = segment_length;
|
639
|
-
instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
|
640
|
-
instance.lanes = context->lanes;
|
641
|
-
instance.threads = context->threads;
|
642
|
-
instance.type = type;
|
643
|
-
|
644
|
-
/* 3. Initialization: Hashing inputs, allocating memory, filling first
|
645
|
-
* blocks
|
646
|
-
*/
|
647
|
-
result = initialize(&instance, context);
|
648
|
-
|
649
|
-
if (ARGON2_OK != result) {
|
650
|
-
return result;
|
651
|
-
}
|
652
|
-
|
653
|
-
/* 4. Filling memory */
|
654
|
-
fill_memory_blocks(&instance);
|
655
|
-
|
656
|
-
/* 5. Finalization */
|
657
|
-
finalize(context, &instance);
|
658
|
-
|
659
|
-
return ARGON2_OK;
|
660
|
-
}
|
@@ -33,8 +33,8 @@ enum argon2_core_constants {
|
|
33
33
|
|
34
34
|
/* Memory block size in bytes */
|
35
35
|
ARGON2_BLOCK_SIZE = 1024,
|
36
|
-
|
37
|
-
|
36
|
+
ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
|
37
|
+
ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
|
38
38
|
|
39
39
|
/* Number of pseudo-random values generated by one call to Blake in Argon2i
|
40
40
|
to
|
@@ -54,7 +54,7 @@ enum argon2_core_constants {
|
|
54
54
|
* Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
|
55
55
|
* bounds checking).
|
56
56
|
*/
|
57
|
-
typedef struct
|
57
|
+
typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
|
58
58
|
|
59
59
|
/*****************Functions that work with the block******************/
|
60
60
|
|
@@ -215,11 +215,4 @@ void fill_segment(const argon2_instance_t *instance,
|
|
215
215
|
*/
|
216
216
|
void fill_memory_blocks(argon2_instance_t *instance);
|
217
217
|
|
218
|
-
/*
|
219
|
-
* Function that performs memory-hard hashing with certain degree of parallelism
|
220
|
-
* @param context Pointer to the Argon2 internal structure
|
221
|
-
* @return Error code if smth is wrong, ARGON2_OK otherwise
|
222
|
-
*/
|
223
|
-
int argon2_core(argon2_context *context, argon2_type type);
|
224
|
-
|
225
218
|
#endif
|
@@ -254,7 +254,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
|
254
254
|
return 0; \
|
255
255
|
} \
|
256
256
|
str += cc_len; \
|
257
|
-
} while (0)
|
257
|
+
} while ((void)0, 0)
|
258
258
|
|
259
259
|
#define CC_opt(prefix, code) \
|
260
260
|
do { \
|
@@ -263,7 +263,7 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
|
263
263
|
str += cc_len; \
|
264
264
|
{ code; } \
|
265
265
|
} \
|
266
|
-
} while (0)
|
266
|
+
} while ((void)0, 0)
|
267
267
|
|
268
268
|
#define DECIMAL(x) \
|
269
269
|
do { \
|
@@ -273,17 +273,17 @@ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
|
|
273
273
|
return 0; \
|
274
274
|
} \
|
275
275
|
(x) = dec_x; \
|
276
|
-
} while (0)
|
276
|
+
} while ((void)0, 0)
|
277
277
|
|
278
278
|
#define BIN(buf, max_len, len) \
|
279
279
|
do { \
|
280
280
|
size_t bin_len = (max_len); \
|
281
281
|
str = from_base64(buf, &bin_len, str); \
|
282
|
-
if (str == NULL) {
|
282
|
+
if (str == NULL || bin_len > UINT32_MAX) { \
|
283
283
|
return 0; \
|
284
284
|
} \
|
285
|
-
(len) = bin_len;
|
286
|
-
} while (0)
|
285
|
+
(len) = (uint32_t)bin_len; \
|
286
|
+
} while ((void)0, 0)
|
287
287
|
|
288
288
|
size_t maxadlen = ctx->adlen;
|
289
289
|
size_t maxsaltlen = ctx->saltlen;
|
@@ -379,14 +379,14 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
379
379
|
memcpy(dst, str, pp_len + 1); \
|
380
380
|
dst += pp_len; \
|
381
381
|
dst_len -= pp_len; \
|
382
|
-
} while (0)
|
382
|
+
} while ((void)0, 0)
|
383
383
|
|
384
384
|
#define SX(x) \
|
385
385
|
do { \
|
386
386
|
char tmp[30]; \
|
387
387
|
sprintf(tmp, "%lu", (unsigned long)(x)); \
|
388
388
|
SS(tmp); \
|
389
|
-
} while (0)
|
389
|
+
} while ((void)0, 0)
|
390
390
|
|
391
391
|
#define SB(buf, len) \
|
392
392
|
do { \
|
@@ -396,7 +396,7 @@ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
|
|
396
396
|
} \
|
397
397
|
dst += sb_len; \
|
398
398
|
dst_len -= sb_len; \
|
399
|
-
} while (0)
|
399
|
+
} while ((void)0, 0)
|
400
400
|
|
401
401
|
if (type == Argon2_i)
|
402
402
|
SS("$argon2i$m=");
|
@@ -114,9 +114,9 @@ void internal_kat(const argon2_instance_t *instance, uint32_t pass) {
|
|
114
114
|
|
115
115
|
for (i = 0; i < instance->memory_blocks; ++i) {
|
116
116
|
uint32_t how_many_words =
|
117
|
-
(instance->memory_blocks >
|
117
|
+
(instance->memory_blocks > ARGON2_QWORDS_IN_BLOCK)
|
118
118
|
? 1
|
119
|
-
:
|
119
|
+
: ARGON2_QWORDS_IN_BLOCK;
|
120
120
|
|
121
121
|
for (j = 0; j < how_many_words; ++j)
|
122
122
|
printf("Block %.4u [%3u]: %016" PRIx64 "\n", i, j,
|
@@ -147,7 +147,7 @@ static void generate_testvectors(const char *type) {
|
|
147
147
|
const deallocate_fptr myown_deallocator = NULL;
|
148
148
|
|
149
149
|
unsigned t_cost = 3;
|
150
|
-
unsigned m_cost =
|
150
|
+
unsigned m_cost = 32;
|
151
151
|
unsigned lanes = 4;
|
152
152
|
|
153
153
|
memset(pwd, 1, TEST_OUTLEN);
|
@@ -15,8 +15,6 @@
|
|
15
15
|
#include <string.h>
|
16
16
|
#include <stdlib.h>
|
17
17
|
|
18
|
-
#include <immintrin.h>
|
19
|
-
|
20
18
|
#include "argon2.h"
|
21
19
|
#include "core.h"
|
22
20
|
#include "opt.h"
|
@@ -25,10 +23,10 @@
|
|
25
23
|
#include "blake2/blamka-round-opt.h"
|
26
24
|
|
27
25
|
void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
28
|
-
__m128i block_XY[
|
26
|
+
__m128i block_XY[ARGON2_OWORDS_IN_BLOCK];
|
29
27
|
uint32_t i;
|
30
28
|
|
31
|
-
for (i = 0; i <
|
29
|
+
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
32
30
|
block_XY[i] = state[i] = _mm_xor_si128(
|
33
31
|
state[i], _mm_loadu_si128((__m128i const *)(&ref_block[16 * i])));
|
34
32
|
}
|
@@ -45,7 +43,7 @@ void fill_block(__m128i *state, const uint8_t *ref_block, uint8_t *next_block) {
|
|
45
43
|
state[8 * 6 + i], state[8 * 7 + i]);
|
46
44
|
}
|
47
45
|
|
48
|
-
for (i = 0; i <
|
46
|
+
for (i = 0; i < ARGON2_OWORDS_IN_BLOCK; i++) {
|
49
47
|
state[i] = _mm_xor_si128(state[i], block_XY[i]);
|
50
48
|
_mm_storeu_si128((__m128i *)(&next_block[16 * i]), state[i]);
|
51
49
|
}
|
@@ -70,8 +68,8 @@ void generate_addresses(const argon2_instance_t *instance,
|
|
70
68
|
|
71
69
|
for (i = 0; i < instance->segment_length; ++i) {
|
72
70
|
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
73
|
-
__m128i zero_block[
|
74
|
-
__m128i zero2_block[
|
71
|
+
__m128i zero_block[ARGON2_OWORDS_IN_BLOCK];
|
72
|
+
__m128i zero2_block[ARGON2_OWORDS_IN_BLOCK];
|
75
73
|
memset(zero_block, 0, sizeof(zero_block));
|
76
74
|
memset(zero2_block, 0, sizeof(zero2_block));
|
77
75
|
input_block.v[6]++;
|
@@ -14,6 +14,11 @@
|
|
14
14
|
#ifndef ARGON2_OPT_H
|
15
15
|
#define ARGON2_OPT_H
|
16
16
|
|
17
|
+
#include <stdint.h>
|
18
|
+
#include <emmintrin.h>
|
19
|
+
#include "argon2.h"
|
20
|
+
#include "core.h"
|
21
|
+
|
17
22
|
/*
|
18
23
|
* Function fills a new memory block. Differs from the
|
19
24
|
* @param state Pointer to the just produced block. Content will be updated(!)
|
data/lib/argon2.rb
CHANGED
@@ -17,10 +17,6 @@ module Argon2
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def hash(pass)
|
20
|
-
# It is technically possible to include NULL bytes, however our C
|
21
|
-
# uses strlen(). It is not deemed suitable to accept a user password
|
22
|
-
# with such a character.
|
23
|
-
raise ArgonHashFail, "NULL bytes not permitted" if /\0/.match(pass)
|
24
20
|
Argon2::Engine.hash_argon2i_encode(
|
25
21
|
pass, @salt, @t_cost, @m_cost, @secret)
|
26
22
|
end
|
data/lib/argon2/ffi_engine.rb
CHANGED
@@ -16,14 +16,16 @@ module Argon2
|
|
16
16
|
:uint, :uint, :uint, :pointer,
|
17
17
|
:size_t, :pointer, :size_t, :pointer, :size_t], :int, :blocking => true
|
18
18
|
|
19
|
-
#void argon2_wrap(uint8_t *out, char *pwd,
|
19
|
+
#void argon2_wrap(uint8_t *out, char *pwd, size_it pwdlen,
|
20
|
+
#uint8_t *salt, uint32_t t_cost,
|
20
21
|
# uint32_t m_cost, uint32_t lanes,
|
21
22
|
# uint8_t *secret, uint32_t secretlen)
|
22
23
|
attach_function :argon2_wrap, [
|
23
|
-
:pointer, :pointer, :pointer, :uint,
|
24
|
+
:pointer, :pointer, :size_t, :pointer, :uint,
|
24
25
|
:uint, :uint, :pointer, :size_t], :uint, :blocking => true
|
25
26
|
|
26
|
-
#int argon2i_verify(const char *encoded, const void *pwd,
|
27
|
+
#int argon2i_verify(const char *encoded, const void *pwd,
|
28
|
+
#const size_t pwdlen);
|
27
29
|
attach_function :wrap_argon2_verify, [:pointer, :pointer, :size_t,
|
28
30
|
:pointer, :size_t], :int, :blocking => true
|
29
31
|
end
|
@@ -46,11 +48,13 @@ module Argon2
|
|
46
48
|
def self.hash_argon2i_encode(password, salt, t_cost, m_cost, secret)
|
47
49
|
result = ''
|
48
50
|
secretlen = secret.nil? ? 0 : secret.length
|
51
|
+
passwordlen = password.nil? ? 0 : password.length
|
49
52
|
if salt.length != Constants::SALT_LEN
|
50
53
|
raise ArgonHashFail, "Invalid salt size"
|
51
54
|
end
|
52
55
|
FFI::MemoryPointer.new(:char, Constants::ENCODE_LEN) do |buffer|
|
53
|
-
ret = Ext.argon2_wrap(buffer, password,
|
56
|
+
ret = Ext.argon2_wrap(buffer, password, passwordlen,
|
57
|
+
salt, t_cost, (1 << m_cost),
|
54
58
|
1, secret, secretlen)
|
55
59
|
raise ArgonHashFail, ERRORS[ret] unless ret == 0
|
56
60
|
result = buffer.read_string(Constants::ENCODE_LEN)
|