enzoic 1.0.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (106) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +19 -0
  3. data/.gitmodules +3 -0
  4. data/.travis.yml +3 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE +5 -0
  7. data/README.md +90 -0
  8. data/Rakefile +28 -0
  9. data/enzoic.gemspec +36 -0
  10. data/ext/.DS_Store +0 -0
  11. data/ext/argon2-wrapper/Makefile +74 -0
  12. data/ext/argon2-wrapper/argon2-wrapper.c +165 -0
  13. data/ext/argon2-wrapper/extconf.rb +1 -0
  14. data/ext/argon2_import/.DS_Store +0 -0
  15. data/ext/digest/whirlpool/extconf.rb +10 -0
  16. data/ext/digest/whirlpool/whirlpool-algorithm.c +476 -0
  17. data/ext/digest/whirlpool/whirlpool-algorithm.h +86 -0
  18. data/ext/digest/whirlpool/whirlpool-constants.h +1116 -0
  19. data/ext/digest/whirlpool/whirlpool-portability.h +142 -0
  20. data/ext/digest/whirlpool/whirlpool.c +51 -0
  21. data/ext/phc-winner-argon2/.gitattributes +10 -0
  22. data/ext/phc-winner-argon2/.gitignore +21 -0
  23. data/ext/phc-winner-argon2/.travis.yml +14 -0
  24. data/ext/phc-winner-argon2/Argon2.sln +160 -0
  25. data/ext/phc-winner-argon2/CHANGELOG.md +25 -0
  26. data/ext/phc-winner-argon2/LICENSE +314 -0
  27. data/ext/phc-winner-argon2/Makefile +187 -0
  28. data/ext/phc-winner-argon2/README.md +290 -0
  29. data/ext/phc-winner-argon2/appveyor.yml +25 -0
  30. data/ext/phc-winner-argon2/argon2-specs.pdf +0 -0
  31. data/ext/phc-winner-argon2/export.sh +7 -0
  32. data/ext/phc-winner-argon2/include/argon2.h +435 -0
  33. data/ext/phc-winner-argon2/kats/argon2d +12304 -0
  34. data/ext/phc-winner-argon2/kats/argon2d.shasum +1 -0
  35. data/ext/phc-winner-argon2/kats/argon2d_v16 +12304 -0
  36. data/ext/phc-winner-argon2/kats/argon2d_v16.shasum +1 -0
  37. data/ext/phc-winner-argon2/kats/argon2i +12304 -0
  38. data/ext/phc-winner-argon2/kats/argon2i.shasum +1 -0
  39. data/ext/phc-winner-argon2/kats/argon2i_v16 +12304 -0
  40. data/ext/phc-winner-argon2/kats/argon2i_v16.shasum +1 -0
  41. data/ext/phc-winner-argon2/kats/argon2id +12304 -0
  42. data/ext/phc-winner-argon2/kats/argon2id.shasum +1 -0
  43. data/ext/phc-winner-argon2/kats/argon2id_v16 +12304 -0
  44. data/ext/phc-winner-argon2/kats/argon2id_v16.shasum +1 -0
  45. data/ext/phc-winner-argon2/kats/check-sums.ps1 +42 -0
  46. data/ext/phc-winner-argon2/kats/check-sums.sh +13 -0
  47. data/ext/phc-winner-argon2/kats/test.ps1 +50 -0
  48. data/ext/phc-winner-argon2/kats/test.sh +49 -0
  49. data/ext/phc-winner-argon2/latex/IEEEtran.cls +6347 -0
  50. data/ext/phc-winner-argon2/latex/Makefile +18 -0
  51. data/ext/phc-winner-argon2/latex/argon2-specs.tex +920 -0
  52. data/ext/phc-winner-argon2/latex/pics/argon2-par.pdf +0 -0
  53. data/ext/phc-winner-argon2/latex/pics/compression.pdf +0 -0
  54. data/ext/phc-winner-argon2/latex/pics/generic.pdf +0 -0
  55. data/ext/phc-winner-argon2/latex/pics/power-distribution.jpg +0 -0
  56. data/ext/phc-winner-argon2/latex/tradeoff.bib +822 -0
  57. data/ext/phc-winner-argon2/libargon2.pc +16 -0
  58. data/ext/phc-winner-argon2/man/argon2.1 +57 -0
  59. data/ext/phc-winner-argon2/src/argon2.c +452 -0
  60. data/ext/phc-winner-argon2/src/bench.c +111 -0
  61. data/ext/phc-winner-argon2/src/blake2/blake2-impl.h +156 -0
  62. data/ext/phc-winner-argon2/src/blake2/blake2.h +91 -0
  63. data/ext/phc-winner-argon2/src/blake2/blake2b.c +390 -0
  64. data/ext/phc-winner-argon2/src/blake2/blamka-round-opt.h +328 -0
  65. data/ext/phc-winner-argon2/src/blake2/blamka-round-ref.h +56 -0
  66. data/ext/phc-winner-argon2/src/core.c +635 -0
  67. data/ext/phc-winner-argon2/src/core.h +227 -0
  68. data/ext/phc-winner-argon2/src/encoding.c +463 -0
  69. data/ext/phc-winner-argon2/src/encoding.h +57 -0
  70. data/ext/phc-winner-argon2/src/genkat.c +208 -0
  71. data/ext/phc-winner-argon2/src/genkat.h +49 -0
  72. data/ext/phc-winner-argon2/src/opt.c +241 -0
  73. data/ext/phc-winner-argon2/src/ref.c +194 -0
  74. data/ext/phc-winner-argon2/src/run.c +317 -0
  75. data/ext/phc-winner-argon2/src/test.c +254 -0
  76. data/ext/phc-winner-argon2/src/thread.c +57 -0
  77. data/ext/phc-winner-argon2/src/thread.h +67 -0
  78. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj +226 -0
  79. data/ext/phc-winner-argon2/vs2015/Argon2Opt/Argon2Opt.vcxproj.filters +69 -0
  80. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj +226 -0
  81. data/ext/phc-winner-argon2/vs2015/Argon2OptBench/Argon2OptBench.vcxproj.filters +69 -0
  82. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj +225 -0
  83. data/ext/phc-winner-argon2/vs2015/Argon2OptDll/Argon2OptDll.vcxproj.filters +66 -0
  84. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj +239 -0
  85. data/ext/phc-winner-argon2/vs2015/Argon2OptGenKAT/Argon2OptGenKAT.vcxproj.filters +72 -0
  86. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj +227 -0
  87. data/ext/phc-winner-argon2/vs2015/Argon2OptTestCI/Argon2OptTestCI.vcxproj.filters +69 -0
  88. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj +226 -0
  89. data/ext/phc-winner-argon2/vs2015/Argon2Ref/Argon2Ref.vcxproj.filters +69 -0
  90. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj +226 -0
  91. data/ext/phc-winner-argon2/vs2015/Argon2RefBench/Argon2RefBench.vcxproj.filters +69 -0
  92. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj +225 -0
  93. data/ext/phc-winner-argon2/vs2015/Argon2RefDll/Argon2RefDll.vcxproj.filters +66 -0
  94. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj +227 -0
  95. data/ext/phc-winner-argon2/vs2015/Argon2RefGenKAT/Argon2RefGenKAT.vcxproj.filters +72 -0
  96. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj +226 -0
  97. data/ext/phc-winner-argon2/vs2015/Argon2RefTestCI/Argon2RefTestCI.vcxproj.filters +69 -0
  98. data/lib/enzoic.rb +189 -0
  99. data/lib/enzoic/argon2_errors.rb +39 -0
  100. data/lib/enzoic/argon2_wrapper_ffi.rb +89 -0
  101. data/lib/enzoic/constants.rb +10 -0
  102. data/lib/enzoic/errors.rb +3 -0
  103. data/lib/enzoic/hashing.rb +258 -0
  104. data/lib/enzoic/password_type.rb +25 -0
  105. data/lib/enzoic/version.rb +5 -0
  106. metadata +354 -0
@@ -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 : http://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : http://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,317 @@
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 : http://creativecommons.org/publicdomain/zero/1.0
12
+ * - Apache 2.0 : http://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 <inttypes.h>
21
+ #include <stdint.h>
22
+ #include <stdio.h>
23
+ #include <stdlib.h>
24
+ #include <string.h>
25
+ #include <time.h>
26
+
27
+ #include "argon2.h"
28
+ #include "core.h"
29
+
30
+ #define T_COST_DEF 3
31
+ #define LOG_M_COST_DEF 12 /* 2^12 = 4 MiB */
32
+ #define LANES_DEF 1
33
+ #define THREADS_DEF 1
34
+ #define OUTLEN_DEF 32
35
+ #define MAX_PASS_LEN 128
36
+
37
+ #define UNUSED_PARAMETER(x) (void)(x)
38
+
39
+ static void usage(const char *cmd) {
40
+ printf("Usage: %s [-h] salt [-i|-d|-id] [-t iterations] [-m memory] "
41
+ "[-p parallelism] [-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-p N\t\tSets parallelism to N threads (default %d)\n",
54
+ THREADS_DEF);
55
+ printf("\t-l N\t\tSets hash output length to N bytes (default %d)\n",
56
+ OUTLEN_DEF);
57
+ printf("\t-e\t\tOutput only encoded hash\n");
58
+ printf("\t-r\t\tOutput only the raw bytes of the hash\n");
59
+ printf("\t-v (10|13)\tArgon2 version (defaults to the most recent version, currently %x)\n",
60
+ ARGON2_VERSION_NUMBER);
61
+ printf("\t-h\t\tPrint %s usage\n", cmd);
62
+ }
63
+
64
+ static void fatal(const char *error) {
65
+ fprintf(stderr, "Error: %s\n", error);
66
+ exit(1);
67
+ }
68
+
69
+ static void print_hex(uint8_t *bytes, size_t bytes_len) {
70
+ size_t i;
71
+ for (i = 0; i < bytes_len; ++i) {
72
+ printf("%02x", bytes[i]);
73
+ }
74
+ printf("\n");
75
+ }
76
+
77
+ /*
78
+ Runs Argon2 with certain inputs and parameters, inputs not cleared. Prints the
79
+ Base64-encoded hash string
80
+ @out output array with at least 32 bytes allocated
81
+ @pwd NULL-terminated string, presumably from argv[]
82
+ @salt salt array
83
+ @t_cost number of iterations
84
+ @m_cost amount of requested memory in KB
85
+ @lanes amount of requested parallelism
86
+ @threads actual parallelism
87
+ @type Argon2 type we want to run
88
+ @encoded_only display only the encoded hash
89
+ @raw_only display only the hexadecimal of the hash
90
+ @version Argon2 version
91
+ */
92
+ static void run(uint32_t outlen, char *pwd, char *salt, uint32_t t_cost,
93
+ uint32_t m_cost, uint32_t lanes, uint32_t threads,
94
+ argon2_type type, int encoded_only, int raw_only, uint32_t version) {
95
+ clock_t start_time, stop_time;
96
+ size_t pwdlen, saltlen, encodedlen;
97
+ int result;
98
+ unsigned char * out = NULL;
99
+ char * encoded = NULL;
100
+
101
+ start_time = clock();
102
+
103
+ if (!pwd) {
104
+ fatal("password missing");
105
+ }
106
+
107
+ if (!salt) {
108
+ clear_internal_memory(pwd, strlen(pwd));
109
+ fatal("salt missing");
110
+ }
111
+
112
+ pwdlen = strlen(pwd);
113
+ saltlen = strlen(salt);
114
+ if(UINT32_MAX < saltlen) {
115
+ fatal("salt is too long");
116
+ }
117
+
118
+ UNUSED_PARAMETER(lanes);
119
+
120
+ out = malloc(outlen + 1);
121
+ if (!out) {
122
+ clear_internal_memory(pwd, strlen(pwd));
123
+ fatal("could not allocate memory for output");
124
+ }
125
+
126
+ encodedlen = argon2_encodedlen(t_cost, m_cost, lanes, (uint32_t)saltlen, outlen, type);
127
+ encoded = malloc(encodedlen + 1);
128
+ if (!encoded) {
129
+ clear_internal_memory(pwd, strlen(pwd));
130
+ fatal("could not allocate memory for hash");
131
+ }
132
+
133
+ result = argon2_hash(t_cost, m_cost, threads, pwd, pwdlen, salt, saltlen,
134
+ out, outlen, encoded, encodedlen, type,
135
+ version);
136
+ if (result != ARGON2_OK)
137
+ fatal(argon2_error_message(result));
138
+
139
+ stop_time = clock();
140
+
141
+ if (encoded_only)
142
+ puts(encoded);
143
+
144
+ if (raw_only)
145
+ print_hex(out, outlen);
146
+
147
+ if (encoded_only || raw_only) {
148
+ free(out);
149
+ free(encoded);
150
+ return;
151
+ }
152
+
153
+ printf("Hash:\t\t");
154
+ print_hex(out, outlen);
155
+ free(out);
156
+
157
+ printf("Encoded:\t%s\n", encoded);
158
+
159
+ printf("%2.3f seconds\n",
160
+ ((double)stop_time - start_time) / (CLOCKS_PER_SEC));
161
+
162
+ result = argon2_verify(encoded, pwd, pwdlen, type);
163
+ if (result != ARGON2_OK)
164
+ fatal(argon2_error_message(result));
165
+ printf("Verification ok\n");
166
+ free(encoded);
167
+ }
168
+
169
+ int main(int argc, char *argv[]) {
170
+ uint32_t outlen = OUTLEN_DEF;
171
+ uint32_t m_cost = 1 << LOG_M_COST_DEF;
172
+ uint32_t t_cost = T_COST_DEF;
173
+ uint32_t lanes = LANES_DEF;
174
+ uint32_t threads = THREADS_DEF;
175
+ argon2_type type = Argon2_i; /* Argon2i is the default type */
176
+ int types_specified = 0;
177
+ int encoded_only = 0;
178
+ int raw_only = 0;
179
+ uint32_t version = ARGON2_VERSION_NUMBER;
180
+ int i;
181
+ size_t n;
182
+ char pwd[MAX_PASS_LEN], *salt;
183
+
184
+ if (argc < 2) {
185
+ usage(argv[0]);
186
+ return ARGON2_MISSING_ARGS;
187
+ } else if (argc >= 2 && strcmp(argv[1], "-h") == 0) {
188
+ usage(argv[0]);
189
+ return 1;
190
+ }
191
+
192
+ /* get password from stdin */
193
+ n = fread(pwd, 1, sizeof pwd - 1, stdin);
194
+ if(n < 1) {
195
+ fatal("no password read");
196
+ }
197
+ if(n == MAX_PASS_LEN-1) {
198
+ fatal("Provided password longer than supported in command line utility");
199
+ }
200
+
201
+ pwd[n] = '\0';
202
+ if (pwd[n - 1] == '\n') {
203
+ pwd[n - 1] = '\0';
204
+ }
205
+
206
+ salt = argv[1];
207
+
208
+ /* parse options */
209
+ for (i = 2; i < argc; i++) {
210
+ const char *a = argv[i];
211
+ unsigned long input = 0;
212
+ if (!strcmp(a, "-h")) {
213
+ usage(argv[0]);
214
+ return 1;
215
+ } else if (!strcmp(a, "-m")) {
216
+ if (i < argc - 1) {
217
+ i++;
218
+ input = strtoul(argv[i], NULL, 10);
219
+ if (input == 0 || input == ULONG_MAX ||
220
+ input > ARGON2_MAX_MEMORY_BITS) {
221
+ fatal("bad numeric input for -m");
222
+ }
223
+ m_cost = ARGON2_MIN(UINT64_C(1) << input, UINT32_C(0xFFFFFFFF));
224
+ if (m_cost > ARGON2_MAX_MEMORY) {
225
+ fatal("m_cost overflow");
226
+ }
227
+ continue;
228
+ } else {
229
+ fatal("missing -m argument");
230
+ }
231
+ } else if (!strcmp(a, "-t")) {
232
+ if (i < argc - 1) {
233
+ i++;
234
+ input = strtoul(argv[i], NULL, 10);
235
+ if (input == 0 || input == ULONG_MAX ||
236
+ input > ARGON2_MAX_TIME) {
237
+ fatal("bad numeric input for -t");
238
+ }
239
+ t_cost = input;
240
+ continue;
241
+ } else {
242
+ fatal("missing -t argument");
243
+ }
244
+ } else if (!strcmp(a, "-p")) {
245
+ if (i < argc - 1) {
246
+ i++;
247
+ input = strtoul(argv[i], NULL, 10);
248
+ if (input == 0 || input == ULONG_MAX ||
249
+ input > ARGON2_MAX_THREADS || input > ARGON2_MAX_LANES) {
250
+ fatal("bad numeric input for -p");
251
+ }
252
+ threads = input;
253
+ lanes = threads;
254
+ continue;
255
+ } else {
256
+ fatal("missing -p argument");
257
+ }
258
+ } else if (!strcmp(a, "-l")) {
259
+ if (i < argc - 1) {
260
+ i++;
261
+ input = strtoul(argv[i], NULL, 10);
262
+ outlen = input;
263
+ continue;
264
+ } else {
265
+ fatal("missing -l argument");
266
+ }
267
+ } else if (!strcmp(a, "-i")) {
268
+ type = Argon2_i;
269
+ ++types_specified;
270
+ } else if (!strcmp(a, "-d")) {
271
+ type = Argon2_d;
272
+ ++types_specified;
273
+ } else if (!strcmp(a, "-id")) {
274
+ type = Argon2_id;
275
+ ++types_specified;
276
+ } else if (!strcmp(a, "-e")) {
277
+ encoded_only = 1;
278
+ } else if (!strcmp(a, "-r")) {
279
+ raw_only = 1;
280
+ } else if (!strcmp(a, "-v")) {
281
+ if (i < argc - 1) {
282
+ i++;
283
+ if (!strcmp(argv[i], "10")) {
284
+ version = ARGON2_VERSION_10;
285
+ } else if (!strcmp(argv[i], "13")) {
286
+ version = ARGON2_VERSION_13;
287
+ } else {
288
+ fatal("invalid Argon2 version");
289
+ }
290
+ } else {
291
+ fatal("missing -v argument");
292
+ }
293
+ } else {
294
+ fatal("unknown argument");
295
+ }
296
+ }
297
+
298
+ if (types_specified > 1) {
299
+ fatal("cannot specify multiple Argon2 types");
300
+ }
301
+
302
+ if(encoded_only && raw_only)
303
+ fatal("cannot provide both -e and -r");
304
+
305
+ if(!encoded_only && !raw_only) {
306
+ printf("Type:\t\t%s\n", argon2_type2string(type, 1));
307
+ printf("Iterations:\t%" PRIu32 " \n", t_cost);
308
+ printf("Memory:\t\t%" PRIu32 " KiB\n", m_cost);
309
+ printf("Parallelism:\t%" PRIu32 " \n", lanes);
310
+ }
311
+
312
+ run(outlen, pwd, salt, t_cost, m_cost, lanes, threads, type,
313
+ encoded_only, raw_only, version);
314
+
315
+ return ARGON2_OK;
316
+ }
317
+