argon2 2.3.1 → 2.3.3

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.
Files changed (85) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +1 -1
  3. data/.rubocop.yml +2 -1
  4. data/argon2.gemspec +2 -2
  5. data/ext/phc-winner-argon2/.git +1 -0
  6. data/ext/phc-winner-argon2/.gitattributes +10 -0
  7. data/ext/phc-winner-argon2/.gitignore +22 -0
  8. data/ext/phc-winner-argon2/.travis.yml +25 -0
  9. data/ext/phc-winner-argon2/Argon2.sln +158 -0
  10. data/ext/phc-winner-argon2/CHANGELOG.md +32 -0
  11. data/ext/phc-winner-argon2/LICENSE +314 -0
  12. data/ext/phc-winner-argon2/Makefile +255 -0
  13. data/ext/phc-winner-argon2/Package.swift +46 -0
  14. data/ext/phc-winner-argon2/README.md +303 -0
  15. data/ext/phc-winner-argon2/appveyor.yml +25 -0
  16. data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
  17. data/ext/phc-winner-argon2/export.sh +7 -0
  18. data/ext/phc-winner-argon2/include/argon2.h +437 -0
  19. data/ext/phc-winner-argon2/kats/argon2d +12304 -0
  20. data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -0
  21. data/ext/phc-winner-argon2/kats/argon2d_v16 +12304 -0
  22. data/ext/phc-winner-argon2/kats/argon2d_v16.shasum +1 -0
  23. data/ext/phc-winner-argon2/kats/argon2i +12304 -0
  24. data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -0
  25. data/ext/phc-winner-argon2/kats/argon2i_v16 +12304 -0
  26. data/ext/phc-winner-argon2/kats/argon2i_v16.shasum +1 -0
  27. data/ext/phc-winner-argon2/kats/argon2id +12304 -0
  28. data/ext/phc-winner-argon2/kats/argon2id.shasum +1 -0
  29. data/ext/phc-winner-argon2/kats/argon2id_v16 +12304 -0
  30. data/ext/phc-winner-argon2/kats/argon2id_v16.shasum +1 -0
  31. data/ext/phc-winner-argon2/kats/check-sums.ps1 +42 -0
  32. data/ext/phc-winner-argon2/kats/check-sums.sh +13 -0
  33. data/ext/phc-winner-argon2/kats/test.ps1 +50 -0
  34. data/ext/phc-winner-argon2/kats/test.sh +49 -0
  35. data/ext/phc-winner-argon2/latex/IEEEtran.cls +6347 -0
  36. data/ext/phc-winner-argon2/latex/Makefile +18 -0
  37. data/ext/phc-winner-argon2/latex/argon2-specs.tex +920 -0
  38. data/ext/phc-winner-argon2/latex/pics/argon2-par.pdf +0 -0
  39. data/ext/phc-winner-argon2/latex/pics/compression.pdf +0 -0
  40. data/ext/phc-winner-argon2/latex/pics/generic.pdf +0 -0
  41. data/ext/phc-winner-argon2/latex/pics/power-distribution.jpg +0 -0
  42. data/ext/phc-winner-argon2/latex/tradeoff.bib +822 -0
  43. data/ext/phc-winner-argon2/libargon2.pc.in +18 -0
  44. data/ext/phc-winner-argon2/man/argon2.1 +57 -0
  45. data/ext/phc-winner-argon2/src/argon2.c +452 -0
  46. data/ext/phc-winner-argon2/src/bench.c +111 -0
  47. data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +156 -0
  48. data/ext/phc-winner-argon2/src/blake2/blake2.h +89 -0
  49. data/ext/phc-winner-argon2/src/blake2/blake2b.c +390 -0
  50. data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +471 -0
  51. data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +56 -0
  52. data/ext/phc-winner-argon2/src/core.c +648 -0
  53. data/ext/phc-winner-argon2/src/core.h +228 -0
  54. data/ext/phc-winner-argon2/src/encoding.c +463 -0
  55. data/ext/phc-winner-argon2/src/encoding.h +57 -0
  56. data/ext/phc-winner-argon2/src/genkat.c +213 -0
  57. data/ext/phc-winner-argon2/src/genkat.h +51 -0
  58. data/ext/phc-winner-argon2/src/opt.c +283 -0
  59. data/ext/phc-winner-argon2/src/ref.c +194 -0
  60. data/ext/phc-winner-argon2/src/run.c +337 -0
  61. data/ext/phc-winner-argon2/src/test.c +289 -0
  62. data/ext/phc-winner-argon2/src/thread.c +57 -0
  63. data/ext/phc-winner-argon2/src/thread.h +67 -0
  64. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +231 -0
  65. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters +69 -0
  66. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +231 -0
  67. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters +69 -0
  68. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +230 -0
  69. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +66 -0
  70. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +244 -0
  71. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters +72 -0
  72. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +235 -0
  73. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters +69 -0
  74. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +243 -0
  75. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters +69 -0
  76. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +231 -0
  77. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters +69 -0
  78. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +230 -0
  79. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +66 -0
  80. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +232 -0
  81. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters +72 -0
  82. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +231 -0
  83. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters +69 -0
  84. data/lib/argon2/version.rb +1 -1
  85. metadata +85 -6
@@ -0,0 +1,194 @@
1
+ /*
2
+ * Argon2 reference source code package - reference C implementations
3
+ *
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
6
+ *
7
+ * You may use this work under the terms of a Creative Commons CC0 1.0
8
+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9
+ * these licenses can be found at:
10
+ *
11
+ * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * You should have received a copy of both of these licenses along with this
15
+ * software. If not, they may be obtained at the above URLs.
16
+ */
17
+
18
+ #include <stdint.h>
19
+ #include <string.h>
20
+ #include <stdlib.h>
21
+
22
+ #include "argon2.h"
23
+ #include "core.h"
24
+
25
+ #include "blake2/blamka-round-ref.h"
26
+ #include "blake2/blake2-impl.h"
27
+ #include "blake2/blake2.h"
28
+
29
+
30
+ /*
31
+ * Function fills a new memory block and optionally XORs the old block over the new one.
32
+ * @next_block must be initialized.
33
+ * @param prev_block Pointer to the previous block
34
+ * @param ref_block Pointer to the reference block
35
+ * @param next_block Pointer to the block to be constructed
36
+ * @param with_xor Whether to XOR into the new block (1) or just overwrite (0)
37
+ * @pre all block pointers must be valid
38
+ */
39
+ static void fill_block(const block *prev_block, const block *ref_block,
40
+ block *next_block, int with_xor) {
41
+ block blockR, block_tmp;
42
+ unsigned i;
43
+
44
+ copy_block(&blockR, ref_block);
45
+ xor_block(&blockR, prev_block);
46
+ copy_block(&block_tmp, &blockR);
47
+ /* Now blockR = ref_block + prev_block and block_tmp = ref_block + prev_block */
48
+ if (with_xor) {
49
+ /* Saving the next block contents for XOR over: */
50
+ xor_block(&block_tmp, next_block);
51
+ /* Now blockR = ref_block + prev_block and
52
+ block_tmp = ref_block + prev_block + next_block */
53
+ }
54
+
55
+ /* Apply Blake2 on columns of 64-bit words: (0,1,...,15) , then
56
+ (16,17,..31)... finally (112,113,...127) */
57
+ for (i = 0; i < 8; ++i) {
58
+ BLAKE2_ROUND_NOMSG(
59
+ blockR.v[16 * i], blockR.v[16 * i + 1], blockR.v[16 * i + 2],
60
+ blockR.v[16 * i + 3], blockR.v[16 * i + 4], blockR.v[16 * i + 5],
61
+ blockR.v[16 * i + 6], blockR.v[16 * i + 7], blockR.v[16 * i + 8],
62
+ blockR.v[16 * i + 9], blockR.v[16 * i + 10], blockR.v[16 * i + 11],
63
+ blockR.v[16 * i + 12], blockR.v[16 * i + 13], blockR.v[16 * i + 14],
64
+ blockR.v[16 * i + 15]);
65
+ }
66
+
67
+ /* Apply Blake2 on rows of 64-bit words: (0,1,16,17,...112,113), then
68
+ (2,3,18,19,...,114,115).. finally (14,15,30,31,...,126,127) */
69
+ for (i = 0; i < 8; i++) {
70
+ BLAKE2_ROUND_NOMSG(
71
+ blockR.v[2 * i], blockR.v[2 * i + 1], blockR.v[2 * i + 16],
72
+ blockR.v[2 * i + 17], blockR.v[2 * i + 32], blockR.v[2 * i + 33],
73
+ blockR.v[2 * i + 48], blockR.v[2 * i + 49], blockR.v[2 * i + 64],
74
+ blockR.v[2 * i + 65], blockR.v[2 * i + 80], blockR.v[2 * i + 81],
75
+ blockR.v[2 * i + 96], blockR.v[2 * i + 97], blockR.v[2 * i + 112],
76
+ blockR.v[2 * i + 113]);
77
+ }
78
+
79
+ copy_block(next_block, &block_tmp);
80
+ xor_block(next_block, &blockR);
81
+ }
82
+
83
+ static void next_addresses(block *address_block, block *input_block,
84
+ const block *zero_block) {
85
+ input_block->v[6]++;
86
+ fill_block(zero_block, input_block, address_block, 0);
87
+ fill_block(zero_block, address_block, address_block, 0);
88
+ }
89
+
90
+ void fill_segment(const argon2_instance_t *instance,
91
+ argon2_position_t position) {
92
+ block *ref_block = NULL, *curr_block = NULL;
93
+ block address_block, input_block, zero_block;
94
+ uint64_t pseudo_rand, ref_index, ref_lane;
95
+ uint32_t prev_offset, curr_offset;
96
+ uint32_t starting_index;
97
+ uint32_t i;
98
+ int data_independent_addressing;
99
+
100
+ if (instance == NULL) {
101
+ return;
102
+ }
103
+
104
+ data_independent_addressing =
105
+ (instance->type == Argon2_i) ||
106
+ (instance->type == Argon2_id && (position.pass == 0) &&
107
+ (position.slice < ARGON2_SYNC_POINTS / 2));
108
+
109
+ if (data_independent_addressing) {
110
+ init_block_value(&zero_block, 0);
111
+ init_block_value(&input_block, 0);
112
+
113
+ input_block.v[0] = position.pass;
114
+ input_block.v[1] = position.lane;
115
+ input_block.v[2] = position.slice;
116
+ input_block.v[3] = instance->memory_blocks;
117
+ input_block.v[4] = instance->passes;
118
+ input_block.v[5] = instance->type;
119
+ }
120
+
121
+ starting_index = 0;
122
+
123
+ if ((0 == position.pass) && (0 == position.slice)) {
124
+ starting_index = 2; /* we have already generated the first two blocks */
125
+
126
+ /* Don't forget to generate the first block of addresses: */
127
+ if (data_independent_addressing) {
128
+ next_addresses(&address_block, &input_block, &zero_block);
129
+ }
130
+ }
131
+
132
+ /* Offset of the current block */
133
+ curr_offset = position.lane * instance->lane_length +
134
+ position.slice * instance->segment_length + starting_index;
135
+
136
+ if (0 == curr_offset % instance->lane_length) {
137
+ /* Last block in this lane */
138
+ prev_offset = curr_offset + instance->lane_length - 1;
139
+ } else {
140
+ /* Previous block */
141
+ prev_offset = curr_offset - 1;
142
+ }
143
+
144
+ for (i = starting_index; i < instance->segment_length;
145
+ ++i, ++curr_offset, ++prev_offset) {
146
+ /*1.1 Rotating prev_offset if needed */
147
+ if (curr_offset % instance->lane_length == 1) {
148
+ prev_offset = curr_offset - 1;
149
+ }
150
+
151
+ /* 1.2 Computing the index of the reference block */
152
+ /* 1.2.1 Taking pseudo-random value from the previous block */
153
+ if (data_independent_addressing) {
154
+ if (i % ARGON2_ADDRESSES_IN_BLOCK == 0) {
155
+ next_addresses(&address_block, &input_block, &zero_block);
156
+ }
157
+ pseudo_rand = address_block.v[i % ARGON2_ADDRESSES_IN_BLOCK];
158
+ } else {
159
+ pseudo_rand = instance->memory[prev_offset].v[0];
160
+ }
161
+
162
+ /* 1.2.2 Computing the lane of the reference block */
163
+ ref_lane = ((pseudo_rand >> 32)) % instance->lanes;
164
+
165
+ if ((position.pass == 0) && (position.slice == 0)) {
166
+ /* Can not reference other lanes yet */
167
+ ref_lane = position.lane;
168
+ }
169
+
170
+ /* 1.2.3 Computing the number of possible reference block within the
171
+ * lane.
172
+ */
173
+ position.index = i;
174
+ ref_index = index_alpha(instance, &position, pseudo_rand & 0xFFFFFFFF,
175
+ ref_lane == position.lane);
176
+
177
+ /* 2 Creating a new block */
178
+ ref_block =
179
+ instance->memory + instance->lane_length * ref_lane + ref_index;
180
+ curr_block = instance->memory + curr_offset;
181
+ if (ARGON2_VERSION_10 == instance->version) {
182
+ /* version 1.2.1 and earlier: overwrite, not XOR */
183
+ fill_block(instance->memory + prev_offset, ref_block, curr_block, 0);
184
+ } else {
185
+ if(0 == position.pass) {
186
+ fill_block(instance->memory + prev_offset, ref_block,
187
+ curr_block, 0);
188
+ } else {
189
+ fill_block(instance->memory + prev_offset, ref_block,
190
+ curr_block, 1);
191
+ }
192
+ }
193
+ }
194
+ }
@@ -0,0 +1,337 @@
1
+ /*
2
+ * Argon2 reference source code package - reference C implementations
3
+ *
4
+ * Copyright 2015
5
+ * Daniel Dinu, Dmitry Khovratovich, Jean-Philippe Aumasson, and Samuel Neves
6
+ *
7
+ * You may use this work under the terms of a Creative Commons CC0 1.0
8
+ * License/Waiver or the Apache Public License 2.0, at your option. The terms of
9
+ * these licenses can be found at:
10
+ *
11
+ * - CC0 1.0 Universal : https://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : https://www.apache.org/licenses/LICENSE-2.0
13
+ *
14
+ * You should have received a copy of both of these licenses along with this
15
+ * software. If not, they may be obtained at the above URLs.
16
+ */
17
+
18
+ #define _GNU_SOURCE 1
19
+
20
+ #include <stdint.h>
21
+ #include <stdio.h>
22
+ #include <stdlib.h>
23
+ #include <string.h>
24
+ #include <time.h>
25
+
26
+ #include "argon2.h"
27
+ #include "core.h"
28
+
29
+ #define T_COST_DEF 3
30
+ #define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */
31
+ #define LANES_DEF 1
32
+ #define THREADS_DEF 1
33
+ #define OUTLEN_DEF 32
34
+ #define MAX_PASS_LEN 128
35
+
36
+ #define UNUSED_PARAMETER(x) (void)(x)
37
+
38
+ static void usage(const char *cmd) {
39
+ printf("Usage: %s [-h] salt [-i|-d|-id] [-t iterations] "
40
+ "[-m log2(memory in KiB) | -k memory in KiB] [-p parallelism] "
41
+ "[-l hash length] [-e|-r] [-v (10|13)]\n",
42
+ cmd);
43
+ printf("\tPassword is read from stdin\n");
44
+ printf("Parameters:\n");
45
+ printf("\tsalt\t\tThe salt to use, at least 8 characters\n");
46
+ printf("\t-i\t\tUse Argon2i (this is the default)\n");
47
+ printf("\t-d\t\tUse Argon2d instead of Argon2i\n");
48
+ printf("\t-id\t\tUse Argon2id instead of Argon2i\n");
49
+ printf("\t-t N\t\tSets the number of iterations to N (default = %d)\n",
50
+ T_COST_DEF);
51
+ printf("\t-m N\t\tSets the memory usage of 2^N KiB (default %d)\n",
52
+ LOG_M_COST_DEF);
53
+ printf("\t-k N\t\tSets the memory usage of N KiB (default %d)\n",
54
+ 1 << LOG_M_COST_DEF);
55
+ printf("\t-p N\t\tSets parallelism to N threads (default %d)\n",
56
+ THREADS_DEF);
57
+ printf("\t-l N\t\tSets hash output length to N bytes (default %d)\n",
58
+ OUTLEN_DEF);
59
+ printf("\t-e\t\tOutput only encoded hash\n");
60
+ printf("\t-r\t\tOutput only the raw bytes of the hash\n");
61
+ printf("\t-v (10|13)\tArgon2 version (defaults to the most recent version, currently %x)\n",
62
+ ARGON2_VERSION_NUMBER);
63
+ printf("\t-h\t\tPrint %s usage\n", cmd);
64
+ }
65
+
66
+ static void fatal(const char *error) {
67
+ fprintf(stderr, "Error: %s\n", error);
68
+ exit(1);
69
+ }
70
+
71
+ static void print_hex(uint8_t *bytes, size_t bytes_len) {
72
+ size_t i;
73
+ for (i = 0; i < bytes_len; ++i) {
74
+ printf("%02x", bytes[i]);
75
+ }
76
+ printf("\n");
77
+ }
78
+
79
+ /*
80
+ Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the
81
+ Base64-encoded hash string
82
+ @out output array with at least 32 bytes allocated
83
+ @pwd NULL-terminated string, presumably from argv[]
84
+ @salt salt array
85
+ @t_cost number of iterations
86
+ @m_cost amount of requested memory in KB
87
+ @lanes amount of requested parallelism
88
+ @threads actual parallelism
89
+ @type Argon2 type we want to run
90
+ @encoded_only display only the encoded hash
91
+ @raw_only display only the hexadecimal of the hash
92
+ @version Argon2 version
93
+ */
94
+ static void run(uint32_t outlen, char *pwd, size_t pwdlen, char *salt, uint32_t t_cost,
95
+ uint32_t m_cost, uint32_t lanes, uint32_t threads,
96
+ argon2_type type, int encoded_only, int raw_only, uint32_t version) {
97
+ clock_t start_time, stop_time;
98
+ size_t saltlen, encodedlen;
99
+ int result;
100
+ unsigned char * out = NULL;
101
+ char * encoded = NULL;
102
+
103
+ start_time = clock();
104
+
105
+ if (!pwd) {
106
+ fatal("password missing");
107
+ }
108
+
109
+ if (!salt) {
110
+ clear_internal_memory(pwd, pwdlen);
111
+ fatal("salt missing");
112
+ }
113
+
114
+ saltlen = strlen(salt);
115
+ if(UINT32_MAX < saltlen) {
116
+ fatal("salt is too long");
117
+ }
118
+
119
+ UNUSED_PARAMETER(lanes);
120
+
121
+ out = malloc(outlen + 1);
122
+ if (!out) {
123
+ clear_internal_memory(pwd, pwdlen);
124
+ fatal("could not allocate memory for output");
125
+ }
126
+
127
+ encodedlen = argon2_encodedlen(t_cost, m_cost, lanes, (uint32_t)saltlen, outlen, type);
128
+ encoded = malloc(encodedlen + 1);
129
+ if (!encoded) {
130
+ clear_internal_memory(pwd, pwdlen);
131
+ fatal("could not allocate memory for hash");
132
+ }
133
+
134
+ result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen,
135
+ out, outlen, encoded, encodedlen, type,
136
+ version);
137
+ if (result != ARGON2_OK)
138
+ fatal(argon2_error_message(result));
139
+
140
+ stop_time = clock();
141
+
142
+ if (encoded_only)
143
+ puts(encoded);
144
+
145
+ if (raw_only)
146
+ print_hex(out, outlen);
147
+
148
+ if (encoded_only || raw_only) {
149
+ free(out);
150
+ free(encoded);
151
+ return;
152
+ }
153
+
154
+ printf("Hash:\t\t");
155
+ print_hex(out, outlen);
156
+ free(out);
157
+
158
+ printf("Encoded:\t%s\n", encoded);
159
+
160
+ printf("%2.3f seconds\n",
161
+ ((double)stop_time - start_time) / (CLOCKS_PER_SEC));
162
+
163
+ result = argon2_verify(encoded, pwd, pwdlen, type);
164
+ if (result != ARGON2_OK)
165
+ fatal(argon2_error_message(result));
166
+ printf("Verification ok\n");
167
+ free(encoded);
168
+ }
169
+
170
+ int main(int argc, char *argv[]) {
171
+ uint32_t outlen = OUTLEN_DEF;
172
+ uint32_t m_cost = 1 << LOG_M_COST_DEF;
173
+ uint32_t t_cost = T_COST_DEF;
174
+ uint32_t lanes = LANES_DEF;
175
+ uint32_t threads = THREADS_DEF;
176
+ argon2_type type = Argon2_i; /* Argon2i is the default type */
177
+ int types_specified = 0;
178
+ int m_cost_specified = 0;
179
+ int encoded_only = 0;
180
+ int raw_only = 0;
181
+ uint32_t version = ARGON2_VERSION_NUMBER;
182
+ int i;
183
+ size_t pwdlen;
184
+ char pwd[MAX_PASS_LEN], *salt;
185
+
186
+ if (argc < 2) {
187
+ usage(argv[0]);
188
+ return ARGON2_MISSING_ARGS;
189
+ } else if (argc >= 2 && strcmp(argv[1], "-h") == 0) {
190
+ usage(argv[0]);
191
+ return 1;
192
+ }
193
+
194
+ /* get password from stdin */
195
+ pwdlen = fread(pwd, 1, sizeof pwd, stdin);
196
+ if(pwdlen < 1) {
197
+ fatal("no password read");
198
+ }
199
+ if(pwdlen == MAX_PASS_LEN) {
200
+ fatal("Provided password longer than supported in command line utility");
201
+ }
202
+
203
+ salt = argv[1];
204
+
205
+ /* parse options */
206
+ for (i = 2; i < argc; i++) {
207
+ const char *a = argv[i];
208
+ unsigned long input = 0;
209
+ if (!strcmp(a, "-h")) {
210
+ usage(argv[0]);
211
+ return 1;
212
+ } else if (!strcmp(a, "-m")) {
213
+ if (m_cost_specified) {
214
+ fatal("-m or -k can only be used once");
215
+ }
216
+ m_cost_specified = 1;
217
+ if (i < argc - 1) {
218
+ i++;
219
+ input = strtoul(argv[i], NULL, 10);
220
+ if (input == 0 || input == ULONG_MAX ||
221
+ input > ARGON2_MAX_MEMORY_BITS) {
222
+ fatal("bad numeric input for -m");
223
+ }
224
+ m_cost = ARGON2_MIN(UINT64_C(1) << input, UINT32_C(0xFFFFFFFF));
225
+ if (m_cost > ARGON2_MAX_MEMORY) {
226
+ fatal("m_cost overflow");
227
+ }
228
+ continue;
229
+ } else {
230
+ fatal("missing -m argument");
231
+ }
232
+ } else if (!strcmp(a, "-k")) {
233
+ if (m_cost_specified) {
234
+ fatal("-m or -k can only be used once");
235
+ }
236
+ m_cost_specified = 1;
237
+ if (i < argc - 1) {
238
+ i++;
239
+ input = strtoul(argv[i], NULL, 10);
240
+ if (input == 0 || input == ULONG_MAX) {
241
+ fatal("bad numeric input for -k");
242
+ }
243
+ m_cost = ARGON2_MIN(input, UINT32_C(0xFFFFFFFF));
244
+ if (m_cost > ARGON2_MAX_MEMORY) {
245
+ fatal("m_cost overflow");
246
+ }
247
+ continue;
248
+ } else {
249
+ fatal("missing -k argument");
250
+ }
251
+ } else if (!strcmp(a, "-t")) {
252
+ if (i < argc - 1) {
253
+ i++;
254
+ input = strtoul(argv[i], NULL, 10);
255
+ if (input == 0 || input == ULONG_MAX ||
256
+ input > ARGON2_MAX_TIME) {
257
+ fatal("bad numeric input for -t");
258
+ }
259
+ t_cost = input;
260
+ continue;
261
+ } else {
262
+ fatal("missing -t argument");
263
+ }
264
+ } else if (!strcmp(a, "-p")) {
265
+ if (i < argc - 1) {
266
+ i++;
267
+ input = strtoul(argv[i], NULL, 10);
268
+ if (input == 0 || input == ULONG_MAX ||
269
+ input > ARGON2_MAX_THREADS || input > ARGON2_MAX_LANES) {
270
+ fatal("bad numeric input for -p");
271
+ }
272
+ threads = input;
273
+ lanes = threads;
274
+ continue;
275
+ } else {
276
+ fatal("missing -p argument");
277
+ }
278
+ } else if (!strcmp(a, "-l")) {
279
+ if (i < argc - 1) {
280
+ i++;
281
+ input = strtoul(argv[i], NULL, 10);
282
+ outlen = input;
283
+ continue;
284
+ } else {
285
+ fatal("missing -l argument");
286
+ }
287
+ } else if (!strcmp(a, "-i")) {
288
+ type = Argon2_i;
289
+ ++types_specified;
290
+ } else if (!strcmp(a, "-d")) {
291
+ type = Argon2_d;
292
+ ++types_specified;
293
+ } else if (!strcmp(a, "-id")) {
294
+ type = Argon2_id;
295
+ ++types_specified;
296
+ } else if (!strcmp(a, "-e")) {
297
+ encoded_only = 1;
298
+ } else if (!strcmp(a, "-r")) {
299
+ raw_only = 1;
300
+ } else if (!strcmp(a, "-v")) {
301
+ if (i < argc - 1) {
302
+ i++;
303
+ if (!strcmp(argv[i], "10")) {
304
+ version = ARGON2_VERSION_10;
305
+ } else if (!strcmp(argv[i], "13")) {
306
+ version = ARGON2_VERSION_13;
307
+ } else {
308
+ fatal("invalid Argon2 version");
309
+ }
310
+ } else {
311
+ fatal("missing -v argument");
312
+ }
313
+ } else {
314
+ fatal("unknown argument");
315
+ }
316
+ }
317
+
318
+ if (types_specified > 1) {
319
+ fatal("cannot specify multiple Argon2 types");
320
+ }
321
+
322
+ if(encoded_only && raw_only)
323
+ fatal("cannot provide both -e and -r");
324
+
325
+ if(!encoded_only && !raw_only) {
326
+ printf("Type:\t\t%s\n", argon2_type2string(type, 1));
327
+ printf("Iterations:\t%u\n", t_cost);
328
+ printf("Memory:\t\t%u KiB\n", m_cost);
329
+ printf("Parallelism:\t%u\n", lanes);
330
+ }
331
+
332
+ run(outlen, pwd, pwdlen, salt, t_cost, m_cost, lanes, threads, type,
333
+ encoded_only, raw_only, version);
334
+
335
+ return ARGON2_OK;
336
+ }
337
+