argon2 0.1.4 → 1.0.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/.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
|
+
}
|