argon2 0.1.4 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -9
- data/.travis.yml +0 -1
- data/CONTRIBUTING.md +12 -0
- data/Changelog.md +10 -11
- data/README.md +23 -14
- data/ext/argon2_wrap/Makefile +8 -6
- data/ext/argon2_wrap/argon_wrap.c +23 -12
- data/ext/argon2_wrap/test.c +14 -42
- data/ext/phc-winner-argon2/.gitignore +5 -1
- data/ext/phc-winner-argon2/.travis.yml +14 -0
- data/ext/phc-winner-argon2/Makefile +33 -12
- data/ext/phc-winner-argon2/README.md +48 -19
- data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
- data/ext/phc-winner-argon2/{src → include}/argon2.h +137 -137
- data/ext/phc-winner-argon2/kats/argon2d +12290 -12290
- data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -1
- data/ext/phc-winner-argon2/kats/argon2i +12290 -12290
- data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -1
- data/ext/phc-winner-argon2/opt.o +0 -0
- data/ext/phc-winner-argon2/src/argon2.c +125 -145
- data/ext/phc-winner-argon2/src/bench.c +5 -5
- data/ext/phc-winner-argon2/src/core.c +15 -20
- data/ext/phc-winner-argon2/src/core.h +5 -2
- data/ext/phc-winner-argon2/src/encoding.c +45 -72
- data/ext/phc-winner-argon2/src/encoding.h +24 -0
- data/ext/phc-winner-argon2/src/genkat.c +2 -2
- data/ext/phc-winner-argon2/src/opt.c +19 -10
- data/ext/phc-winner-argon2/src/opt.h +5 -17
- data/ext/phc-winner-argon2/src/ref.c +12 -9
- data/ext/phc-winner-argon2/src/ref.h +4 -12
- data/ext/phc-winner-argon2/src/run.c +67 -42
- data/ext/phc-winner-argon2/src/test.c +131 -0
- data/lib/argon2.rb +6 -5
- data/lib/argon2/constants.rb +3 -2
- data/lib/argon2/engine.rb +1 -0
- data/lib/argon2/errors.rb +37 -36
- data/lib/argon2/ffi_engine.rb +10 -10
- data/lib/argon2/version.rb +2 -1
- metadata +7 -12
@@ -16,14 +16,13 @@
|
|
16
16
|
#include <stdlib.h>
|
17
17
|
|
18
18
|
#include "argon2.h"
|
19
|
-
#include "core.h"
|
20
19
|
#include "ref.h"
|
21
20
|
|
22
21
|
#include "blake2/blamka-round-ref.h"
|
23
22
|
#include "blake2/blake2-impl.h"
|
24
23
|
#include "blake2/blake2.h"
|
25
24
|
|
26
|
-
void
|
25
|
+
void fill_block_with_xor(const block *prev_block, const block *ref_block,
|
27
26
|
block *next_block) {
|
28
27
|
block blockR, block_tmp;
|
29
28
|
unsigned i;
|
@@ -31,7 +30,8 @@ void fill_block(const block *prev_block, const block *ref_block,
|
|
31
30
|
copy_block(&blockR, ref_block);
|
32
31
|
xor_block(&blockR, prev_block);
|
33
32
|
copy_block(&block_tmp, &blockR);
|
34
|
-
|
33
|
+
xor_block(&block_tmp, next_block); /*Saving the next block contents for XOR over*/
|
34
|
+
/*Now blockR = ref_block + prev_block and bloc_tmp = ref_block + prev_block + next_block*/
|
35
35
|
/* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
|
36
36
|
(16,17,..31)... finally (112,113,...127) */
|
37
37
|
for (i = 0; i < 8; ++i) {
|
@@ -63,12 +63,11 @@ void fill_block(const block *prev_block, const block *ref_block,
|
|
63
63
|
void generate_addresses(const argon2_instance_t *instance,
|
64
64
|
const argon2_position_t *position,
|
65
65
|
uint64_t *pseudo_rands) {
|
66
|
-
block zero_block, input_block, address_block;
|
66
|
+
block zero_block, input_block, address_block,tmp_block;
|
67
67
|
uint32_t i;
|
68
68
|
|
69
69
|
init_block_value(&zero_block, 0);
|
70
70
|
init_block_value(&input_block, 0);
|
71
|
-
init_block_value(&address_block, 0);
|
72
71
|
|
73
72
|
if (instance != NULL && position != NULL) {
|
74
73
|
input_block.v[0] = position->pass;
|
@@ -81,8 +80,10 @@ void generate_addresses(const argon2_instance_t *instance,
|
|
81
80
|
for (i = 0; i < instance->segment_length; ++i) {
|
82
81
|
if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
|
83
82
|
input_block.v[6]++;
|
84
|
-
|
85
|
-
|
83
|
+
init_block_value(&tmp_block, 0);
|
84
|
+
init_block_value(&address_block, 0);
|
85
|
+
fill_block_with_xor(&zero_block, &input_block, &tmp_block);
|
86
|
+
fill_block_with_xor(&zero_block, &tmp_block, &address_block);
|
86
87
|
}
|
87
88
|
|
88
89
|
pseudo_rands[i] = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
|
@@ -97,7 +98,7 @@ void fill_segment(const argon2_instance_t *instance,
|
|
97
98
|
uint32_t prev_offset, curr_offset;
|
98
99
|
uint32_t starting_index;
|
99
100
|
uint32_t i;
|
100
|
-
int data_independent_addressing
|
101
|
+
int data_independent_addressing;
|
101
102
|
/* Pseudo-random values that determine the reference block position */
|
102
103
|
uint64_t *pseudo_rands = NULL;
|
103
104
|
|
@@ -105,6 +106,8 @@ void fill_segment(const argon2_instance_t *instance,
|
|
105
106
|
return;
|
106
107
|
}
|
107
108
|
|
109
|
+
data_independent_addressing = (instance->type == Argon2_i);
|
110
|
+
|
108
111
|
pseudo_rands =
|
109
112
|
(uint64_t *)malloc(sizeof(uint64_t) * (instance->segment_length));
|
110
113
|
|
@@ -168,7 +171,7 @@ void fill_segment(const argon2_instance_t *instance,
|
|
168
171
|
ref_block =
|
169
172
|
instance->memory + instance->lane_length * ref_lane + ref_index;
|
170
173
|
curr_block = instance->memory + curr_offset;
|
171
|
-
|
174
|
+
fill_block_with_xor(instance->memory + prev_offset, ref_block, curr_block);
|
172
175
|
}
|
173
176
|
|
174
177
|
free(pseudo_rands);
|
@@ -14,14 +14,16 @@
|
|
14
14
|
#ifndef ARGON2_REF_H
|
15
15
|
#define ARGON2_REF_H
|
16
16
|
|
17
|
+
#include "core.h"
|
18
|
+
|
17
19
|
/*
|
18
|
-
* Function fills a new memory block
|
20
|
+
* Function fills a new memory block by XORing over @next_block. @next_block must be initialized
|
19
21
|
* @param prev_block Pointer to the previous block
|
20
22
|
* @param ref_block Pointer to the reference block
|
21
23
|
* @param next_block Pointer to the block to be constructed
|
22
24
|
* @pre all block pointers must be valid
|
23
25
|
*/
|
24
|
-
void
|
26
|
+
void fill_block_with_xor(const block *prev_block, const block *ref_block,
|
25
27
|
block *next_block);
|
26
28
|
|
27
29
|
/*
|
@@ -36,14 +38,4 @@ void generate_addresses(const argon2_instance_t *instance,
|
|
36
38
|
const argon2_position_t *position,
|
37
39
|
uint64_t *pseudo_rands);
|
38
40
|
|
39
|
-
/*
|
40
|
-
* Function that fills the segment using previous segments also from other
|
41
|
-
* threads
|
42
|
-
* @param instance Pointer to the current instance
|
43
|
-
* @param position Current position
|
44
|
-
* @pre all block pointers must be valid
|
45
|
-
*/
|
46
|
-
void fill_segment(const argon2_instance_t *instance,
|
47
|
-
argon2_position_t position);
|
48
|
-
|
49
41
|
#endif /* ARGON2_REF_H */
|
@@ -11,9 +11,11 @@
|
|
11
11
|
* <http://creativecommons.org/publicdomain/zero/1.0/>.
|
12
12
|
*/
|
13
13
|
|
14
|
-
#
|
15
|
-
|
14
|
+
#define _GNU_SOURCE 1
|
15
|
+
|
16
16
|
#include <inttypes.h>
|
17
|
+
#include <stdint.h>
|
18
|
+
#include <stdio.h>
|
17
19
|
#include <stdlib.h>
|
18
20
|
#include <string.h>
|
19
21
|
#include <time.h>
|
@@ -25,34 +27,17 @@
|
|
25
27
|
#define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */
|
26
28
|
#define LANES_DEF 1
|
27
29
|
#define THREADS_DEF 1
|
28
|
-
#define
|
29
|
-
#define SALT_LEN 16
|
30
|
-
/* Sample encode: $argon2i$m=65536,t=2,p=4$c29tZXNhbHQAAAAAAAAAAA$QWLzI4TY9HkL2ZTLc8g6SinwdhZewYrzz9zxCo0bkGY
|
31
|
-
* Maximumum lengths are defined as:
|
32
|
-
* strlen $argon2i$ = 9
|
33
|
-
* m=65536 with strlen (uint32_t)-1 = 10, so this total is 12
|
34
|
-
* ,t=2,p=4 If we consider each number to potentially reach four digits in future, this = 14
|
35
|
-
* $c29tZXNhbHQAAAAAAAAAAA Formula for this is (SALT_LEN * 4 + 3) / 3 + 1 = 23
|
36
|
-
* $QWLzI4TY9HkL2ZTLc8g6SinwdhZewYrzz9zxCo0bkGY per above formula, = 44
|
37
|
-
* + NULL byte
|
38
|
-
* 9 + 12 + 14 + 23 + 44 + 1 = 103
|
39
|
-
* Rounded to 4 byte boundary: 104
|
40
|
-
*
|
41
|
-
* WARNING: 104 is only for the parameters supported by this
|
42
|
-
command-line utility. You'll need a longer ENCODED_LEN to support
|
43
|
-
longer salts and ouputs, as supported by the argon2 library
|
44
|
-
*/
|
45
|
-
#define ENCODED_LEN 108
|
30
|
+
#define OUTLEN_DEF 32
|
46
31
|
|
47
32
|
#define UNUSED_PARAMETER(x) (void)(x)
|
48
33
|
|
49
34
|
static void usage(const char *cmd) {
|
50
35
|
printf("Usage: %s salt [-d] [-t iterations] [-m memory] "
|
51
|
-
"[-p parallelism]\n",
|
36
|
+
"[-p parallelism] [-h hash length]\n",
|
52
37
|
cmd);
|
53
38
|
printf("\tPassword is read from stdin\n");
|
54
39
|
printf("Parameters:\n");
|
55
|
-
printf("\tsalt\t\tThe salt to use, at
|
40
|
+
printf("\tsalt\t\tThe salt to use, at least 8 characters\n");
|
56
41
|
printf("\t-d\t\tUse Argon2d instead of Argon2i (which is the default)\n");
|
57
42
|
printf("\t-t N\t\tSets the number of iterations to N (default = %d)\n",
|
58
43
|
T_COST_DEF);
|
@@ -60,6 +45,8 @@ static void usage(const char *cmd) {
|
|
60
45
|
LOG_M_COST_DEF);
|
61
46
|
printf("\t-p N\t\tSets parallelism to N threads (default %d)\n",
|
62
47
|
THREADS_DEF);
|
48
|
+
printf("\t-h N\t\tSets hash output length to N bytes (default %d)\n",
|
49
|
+
OUTLEN_DEF);
|
63
50
|
}
|
64
51
|
|
65
52
|
static void fatal(const char *error) {
|
@@ -67,24 +54,43 @@ static void fatal(const char *error) {
|
|
67
54
|
exit(1);
|
68
55
|
}
|
69
56
|
|
57
|
+
static uint32_t b64len(uint32_t len) {
|
58
|
+
return ((len + 2) / 3) * 4;
|
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;
|
66
|
+
}
|
67
|
+
return len;
|
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);
|
74
|
+
}
|
75
|
+
|
76
|
+
|
70
77
|
/*
|
71
78
|
Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the
|
72
79
|
Base64-encoded hash string
|
73
80
|
@out output array with at least 32 bytes allocated
|
74
81
|
@pwd NULL-terminated string, presumably from argv[]
|
75
|
-
@salt salt array
|
82
|
+
@salt salt array
|
76
83
|
@t_cost number of iterations
|
77
84
|
@m_cost amount of requested memory in KB
|
78
85
|
@lanes amount of requested parallelism
|
79
86
|
@threads actual parallelism
|
80
87
|
@type String, only "d" and "i" are accepted
|
81
88
|
*/
|
82
|
-
static void run(
|
89
|
+
static void run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost,
|
83
90
|
uint32_t m_cost, uint32_t lanes, uint32_t threads,
|
84
91
|
argon2_type type) {
|
85
92
|
clock_t start_time, stop_time;
|
86
|
-
size_t pwdlen;
|
87
|
-
char encoded[ENCODED_LEN];
|
93
|
+
size_t pwdlen, saltlen, encodedlen;
|
88
94
|
uint32_t i;
|
89
95
|
int result;
|
90
96
|
|
@@ -100,20 +106,35 @@ static void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost,
|
|
100
106
|
}
|
101
107
|
|
102
108
|
pwdlen = strlen(pwd);
|
109
|
+
saltlen = strlen(salt);
|
103
110
|
|
104
111
|
UNUSED_PARAMETER(lanes);
|
105
112
|
|
106
|
-
|
107
|
-
|
113
|
+
unsigned char* out = malloc(outlen + 1);
|
114
|
+
if (!out) {
|
115
|
+
secure_wipe_memory(pwd, strlen(pwd));
|
116
|
+
fatal("could not allocate memory for output");
|
117
|
+
}
|
118
|
+
|
119
|
+
encodedlen = enclen(outlen, saltlen, t_cost, m_cost, lanes);
|
120
|
+
char* encoded = malloc(encodedlen + 1);
|
121
|
+
if (!encoded) {
|
122
|
+
secure_wipe_memory(pwd, strlen(pwd));
|
123
|
+
fatal("could not allocate memory for hash");
|
124
|
+
}
|
125
|
+
|
126
|
+
result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen,
|
127
|
+
out, outlen, encoded, encodedlen, type);
|
108
128
|
if (result != ARGON2_OK)
|
109
|
-
fatal(
|
129
|
+
fatal(argon2_error_message(result));
|
110
130
|
|
111
131
|
stop_time = clock();
|
112
132
|
|
113
133
|
printf("Hash:\t\t");
|
114
|
-
for (i = 0; i <
|
134
|
+
for (i = 0; i < outlen; ++i) {
|
115
135
|
printf("%02x", out[i]);
|
116
136
|
}
|
137
|
+
free(out);
|
117
138
|
printf("\n");
|
118
139
|
printf("Encoded:\t%s\n", encoded);
|
119
140
|
|
@@ -122,27 +143,29 @@ static void run(uint8_t *out, char *pwd, uint8_t *salt, uint32_t t_cost,
|
|
122
143
|
|
123
144
|
result = argon2_verify(encoded, pwd, pwdlen, type);
|
124
145
|
if (result != ARGON2_OK)
|
125
|
-
fatal(
|
146
|
+
fatal(argon2_error_message(result));
|
126
147
|
printf("Verification ok\n");
|
148
|
+
free(encoded);
|
127
149
|
}
|
128
150
|
|
129
151
|
int main(int argc, char *argv[]) {
|
130
|
-
|
152
|
+
uint32_t outlen = OUTLEN_DEF;
|
131
153
|
uint32_t m_cost = 1 << LOG_M_COST_DEF;
|
132
154
|
uint32_t t_cost = T_COST_DEF;
|
133
155
|
uint32_t lanes = LANES_DEF;
|
134
156
|
uint32_t threads = THREADS_DEF;
|
135
|
-
uint8_t salt[SALT_LEN];
|
136
157
|
argon2_type type = Argon2_i;
|
137
158
|
int i;
|
138
159
|
size_t n;
|
139
|
-
char pwd[128];
|
160
|
+
char pwd[128], *salt;
|
140
161
|
|
141
162
|
if (argc < 2) {
|
142
163
|
usage(argv[0]);
|
143
164
|
return ARGON2_MISSING_ARGS;
|
144
165
|
}
|
145
166
|
|
167
|
+
salt = argv[1];
|
168
|
+
|
146
169
|
/* get password from stdin */
|
147
170
|
while ((n = fread(pwd, 1, sizeof pwd - 1, stdin)) > 0) {
|
148
171
|
pwd[n] = '\0';
|
@@ -150,13 +173,6 @@ int main(int argc, char *argv[]) {
|
|
150
173
|
pwd[n - 1] = '\0';
|
151
174
|
}
|
152
175
|
|
153
|
-
/* get salt from command line */
|
154
|
-
if (strlen(argv[1]) > SALT_LEN) {
|
155
|
-
fatal("salt too long");
|
156
|
-
}
|
157
|
-
memset(salt, 0x00, SALT_LEN); /* pad with null bytes */
|
158
|
-
memcpy(salt, argv[1], strlen(argv[1]));
|
159
|
-
|
160
176
|
/* parse options */
|
161
177
|
for (i = 2; i < argc; i++) {
|
162
178
|
const char *a = argv[i];
|
@@ -204,6 +220,15 @@ int main(int argc, char *argv[]) {
|
|
204
220
|
} else {
|
205
221
|
fatal("missing -p argument");
|
206
222
|
}
|
223
|
+
} else if (!strcmp(a, "-h")) {
|
224
|
+
if (i < argc - 1) {
|
225
|
+
i++;
|
226
|
+
input = strtoul(argv[i], NULL, 10);
|
227
|
+
outlen = input;
|
228
|
+
continue;
|
229
|
+
} else {
|
230
|
+
fatal("missing -h argument");
|
231
|
+
}
|
207
232
|
} else if (!strcmp(a, "-d")) {
|
208
233
|
type = Argon2_d;
|
209
234
|
} else {
|
@@ -218,7 +243,7 @@ int main(int argc, char *argv[]) {
|
|
218
243
|
printf("Iterations:\t%" PRIu32 " \n", t_cost);
|
219
244
|
printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost);
|
220
245
|
printf("Parallelism:\t%" PRIu32 " \n", lanes);
|
221
|
-
run(
|
246
|
+
run(outlen, pwd, salt, t_cost, m_cost, lanes, threads, type);
|
222
247
|
|
223
248
|
return ARGON2_OK;
|
224
249
|
}
|
@@ -0,0 +1,131 @@
|
|
1
|
+
#include <stdio.h>
|
2
|
+
#include <stdint.h>
|
3
|
+
#include <inttypes.h>
|
4
|
+
#include <stdlib.h>
|
5
|
+
#include <string.h>
|
6
|
+
#include <time.h>
|
7
|
+
#include <assert.h>
|
8
|
+
|
9
|
+
#include "argon2.h"
|
10
|
+
|
11
|
+
#define OUT_LEN 32
|
12
|
+
#define SALT_LEN 16
|
13
|
+
#define ENCODED_LEN 108
|
14
|
+
|
15
|
+
uint8_t salt[SALT_LEN];
|
16
|
+
|
17
|
+
/* Test harness will assert:
|
18
|
+
* argon_hash2() returns ARGON2_OK
|
19
|
+
* HEX output matches expected
|
20
|
+
* encoded output matches expected
|
21
|
+
* argon2_verify() correctly verifies value
|
22
|
+
*/
|
23
|
+
|
24
|
+
void hashtest(uint32_t t, uint32_t m, uint32_t p, char *pwd, char *hexref,
|
25
|
+
char *mcfref) {
|
26
|
+
unsigned char out[OUT_LEN];
|
27
|
+
unsigned char hex_out[OUT_LEN * 2 + 4];
|
28
|
+
char encoded[ENCODED_LEN];
|
29
|
+
int ret, i;
|
30
|
+
|
31
|
+
printf("Hash test: t=%d, m=%d, p=%d, pass=%s, salt=%s: ", t, m, p, pwd,
|
32
|
+
salt);
|
33
|
+
ret = argon2_hash(t, 1 << m, p, pwd, strlen(pwd), salt, SALT_LEN, out,
|
34
|
+
OUT_LEN, encoded, ENCODED_LEN, Argon2_i);
|
35
|
+
assert(ret == ARGON2_OK);
|
36
|
+
|
37
|
+
for (i = 0; i < OUT_LEN; ++i)
|
38
|
+
sprintf((char *)(hex_out + i * 2), "%02x", out[i]);
|
39
|
+
|
40
|
+
assert(memcmp(hex_out, hexref, OUT_LEN * 2) == 0);
|
41
|
+
assert(memcmp(encoded, mcfref, strlen(mcfref)) == 0);
|
42
|
+
ret = argon2_verify(encoded, pwd, strlen(pwd), Argon2_i);
|
43
|
+
assert(ret == ARGON2_OK);
|
44
|
+
printf("PASS\n");
|
45
|
+
}
|
46
|
+
|
47
|
+
int main() {
|
48
|
+
int ret;
|
49
|
+
unsigned char out[OUT_LEN];
|
50
|
+
char const *msg;
|
51
|
+
|
52
|
+
memset(salt, 0x00, SALT_LEN); /* pad with null bytes */
|
53
|
+
memcpy(salt, "somesalt", 8);
|
54
|
+
|
55
|
+
/* Multiple test cases for various input values */
|
56
|
+
hashtest(2, 16, 1, "password",
|
57
|
+
"1c7eeef9e0e969b3024722fc864a1ca9f6ca20da73f9bf3f1731881beae2039e",
|
58
|
+
"$argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA"
|
59
|
+
"$HH7u+eDpabMCRyL8hkocqfbKINpz+b8/FzGIG+riA54");
|
60
|
+
hashtest(2, 20, 1, "password",
|
61
|
+
"253068ce02908829f9c8a026dc7cf4bd4497fd781faa1665a0d0b10d699e0ebd",
|
62
|
+
"$argon2i$m=1048576,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA"
|
63
|
+
"$JTBozgKQiCn5yKAm3Hz0vUSX/XgfqhZloNCxDWmeDr0");
|
64
|
+
hashtest(2, 18, 1, "password",
|
65
|
+
"5c6dfd2712110cf88f1426059b01d87f8210d5368da0e7ee68586e9d4af4954b",
|
66
|
+
"$argon2i$m=262144,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA"
|
67
|
+
"$XG39JxIRDPiPFCYFmwHYf4IQ1TaNoOfuaFhunUr0lUs");
|
68
|
+
hashtest(2, 8, 1, "password",
|
69
|
+
"dfebf9d4eadd6859f4cc6a9bb20043fd9da7e1e36bdacdbb05ca569f463269f8",
|
70
|
+
"$argon2i$m=256,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA"
|
71
|
+
"$3+v51OrdaFn0zGqbsgBD/Z2n4eNr2s27BcpWn0Yyafg");
|
72
|
+
hashtest(2, 8, 2, "password",
|
73
|
+
"aea9db129d7f8c50d410a6599b0fb3d786a60ec16a3030b9ddd21ee7b6470f7f",
|
74
|
+
"$argon2i$m=256,t=2,p=2$c29tZXNhbHQAAAAAAAAAAA"
|
75
|
+
"$rqnbEp1/jFDUEKZZmw+z14amDsFqMDC53dIe57ZHD38");
|
76
|
+
hashtest(1, 16, 1, "password",
|
77
|
+
"fabd1ddbd86a101d326ac2abe79660202b10192925d2fd2483085df94df0c91a",
|
78
|
+
"$argon2i$m=65536,t=1,p=1$c29tZXNhbHQAAAAAAAAAAA"
|
79
|
+
"$+r0d29hqEB0yasKr55ZgICsQGSkl0v0kgwhd+U3wyRo");
|
80
|
+
hashtest(4, 16, 1, "password",
|
81
|
+
"b3b4cb3d6e2c1cb1e7bffdb966ab3ceafae701d6b7789c3f1e6c6b22d82d99d5",
|
82
|
+
"$argon2i$m=65536,t=4,p=1$c29tZXNhbHQAAAAAAAAAAA"
|
83
|
+
"$s7TLPW4sHLHnv/25Zqs86vrnAda3eJw/HmxrItgtmdU");
|
84
|
+
hashtest(2, 16, 1, "differentpassword",
|
85
|
+
"b2db9d7c0d1288951aec4b6e1cd3835ea29a7da2ac13e6f48554a26b127146f9",
|
86
|
+
"$argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA"
|
87
|
+
"$studfA0SiJUa7EtuHNODXqKafaKsE+b0hVSiaxJxRvk");
|
88
|
+
memcpy(salt, "diffsalt", 8);
|
89
|
+
hashtest(2, 16, 1, "password",
|
90
|
+
"bb6686865f2c1093f70f543c9535f807d5b42d5dc6d71f14a4a7a291913e05e0",
|
91
|
+
"$argon2i$m=65536,t=2,p=1$ZGlmZnNhbHQAAAAAAAAAAA"
|
92
|
+
"$u2aGhl8sEJP3D1Q8lTX4B9W0LV3G1x8UpKeikZE+BeA");
|
93
|
+
|
94
|
+
/* Error state tests */
|
95
|
+
|
96
|
+
ret = argon2_hash(2, 1, 1, "password", strlen("password"), salt, SALT_LEN,
|
97
|
+
out, OUT_LEN, NULL, 0, Argon2_i);
|
98
|
+
assert(ret == ARGON2_MEMORY_TOO_LITTLE);
|
99
|
+
printf("Fail on invalid memory: PASS\n");
|
100
|
+
|
101
|
+
ret = argon2_hash(2, 1 << 12, 1, NULL, strlen("password"), salt, SALT_LEN,
|
102
|
+
out, OUT_LEN, NULL, 0, Argon2_i);
|
103
|
+
assert(ret == ARGON2_PWD_PTR_MISMATCH);
|
104
|
+
printf("Fail on invalid null pointer: PASS\n");
|
105
|
+
|
106
|
+
ret = argon2_hash(2, 1 << 12, 1, "password", strlen("password"), salt, 1,
|
107
|
+
out, OUT_LEN, NULL, 0, Argon2_i);
|
108
|
+
assert(ret == ARGON2_SALT_TOO_SHORT);
|
109
|
+
printf("Fail on salt too short: PASS\n");
|
110
|
+
|
111
|
+
/* Handle an invalid encoding correctly (it is missing a $) */
|
112
|
+
ret = argon2_verify("$argon2i$m=65536,t=2,p=1$"
|
113
|
+
"c29tZXNhbHQAAAAAAAAAAA"
|
114
|
+
"HH7u+eDpabMCRyL8hkocqfbKINpz+b8/FzGIG+riA54",
|
115
|
+
"password", strlen("password"), Argon2_i);
|
116
|
+
assert(ret == ARGON2_DECODING_FAIL);
|
117
|
+
printf("Recognise an invalid encoding: PASS\n");
|
118
|
+
|
119
|
+
/* Handle an mismatching hash (the encoded password is "passwore") */
|
120
|
+
ret = argon2_verify("$argon2i$m=65536,t=2,p=1$c29tZXNhbHQAAAAAAAAAAA"
|
121
|
+
"$tiY53ekuxy5gUQV9pEgGgu3cfe2vKl3l+lKxTna33I4",
|
122
|
+
"password", strlen("password"), Argon2_i);
|
123
|
+
assert(ret == ARGON2_VERIFY_MISMATCH);
|
124
|
+
printf("Verify with mismatched password: PASS\n");
|
125
|
+
|
126
|
+
msg = argon2_error_message(ARGON2_DECODING_FAIL);
|
127
|
+
assert(strcmp(msg, "Decoding failed")==0);
|
128
|
+
printf("Decode an error message: PASS\n");
|
129
|
+
|
130
|
+
return 0;
|
131
|
+
}
|