argon2 0.1.1 → 0.1.2
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 -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)
|