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,227 @@
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
+ #ifndef ARGON2_CORE_H
19
+ #define ARGON2_CORE_H
20
+
21
+ #include "argon2.h"
22
+
23
+ #define CONST_CAST(x) (x)(uintptr_t)
24
+
25
+ /**********************Argon2 internal constants*******************************/
26
+
27
+ enum argon2_core_constants {
28
+ /* Memory block size in bytes */
29
+ ARGON2_BLOCK_SIZE = 1024,
30
+ ARGON2_QWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 8,
31
+ ARGON2_OWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 16,
32
+ ARGON2_HWORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 32,
33
+
34
+ /* Number of pseudo-random values generated by one call to Blake in Argon2i
35
+ to
36
+ generate reference block positions */
37
+ ARGON2_ADDRESSES_IN_BLOCK = 128,
38
+
39
+ /* Pre-hashing digest length and its extension*/
40
+ ARGON2_PREHASH_DIGEST_LENGTH = 64,
41
+ ARGON2_PREHASH_SEED_LENGTH = 72
42
+ };
43
+
44
+ /*************************Argon2 internal data types***********************/
45
+
46
+ /*
47
+ * Structure for the (1KB) memory block implemented as 128 64-bit words.
48
+ * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
49
+ * bounds checking).
50
+ */
51
+ typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
52
+
53
+ /*****************Functions that work with the block******************/
54
+
55
+ /* Initialize each byte of the block with @in */
56
+ void init_block_value(block *b, uint8_t in);
57
+
58
+ /* Copy block @src to block @dst */
59
+ void copy_block(block *dst, const block *src);
60
+
61
+ /* XOR @src onto @dst bytewise */
62
+ void xor_block(block *dst, const block *src);
63
+
64
+ /*
65
+ * Argon2 instance: memory pointer, number of passes, amount of memory, type,
66
+ * and derived values.
67
+ * Used to evaluate the number and location of blocks to construct in each
68
+ * thread
69
+ */
70
+ typedef struct Argon2_instance_t {
71
+ block *memory; /* Memory pointer */
72
+ uint32_t version;
73
+ uint32_t passes; /* Number of passes */
74
+ uint32_t memory_blocks; /* Number of blocks in memory */
75
+ uint32_t segment_length;
76
+ uint32_t lane_length;
77
+ uint32_t lanes;
78
+ uint32_t threads;
79
+ argon2_type type;
80
+ int print_internals; /* whether to print the memory blocks */
81
+ argon2_context *context_ptr; /* points back to original context */
82
+ } argon2_instance_t;
83
+
84
+ /*
85
+ * Argon2 position: where we construct the block right now. Used to distribute
86
+ * work between threads.
87
+ */
88
+ typedef struct Argon2_position_t {
89
+ uint32_t pass;
90
+ uint32_t lane;
91
+ uint8_t slice;
92
+ uint32_t index;
93
+ } argon2_position_t;
94
+
95
+ /*Struct that holds the inputs for thread handling FillSegment*/
96
+ typedef struct Argon2_thread_data {
97
+ argon2_instance_t *instance_ptr;
98
+ argon2_position_t pos;
99
+ } argon2_thread_data;
100
+
101
+ /*************************Argon2 core functions********************************/
102
+
103
+ /* Allocates memory to the given pointer, uses the appropriate allocator as
104
+ * specified in the context. Total allocated memory is num*size.
105
+ * @param context argon2_context which specifies the allocator
106
+ * @param memory pointer to the pointer to the memory
107
+ * @param size the size in bytes for each element to be allocated
108
+ * @param num the number of elements to be allocated
109
+ * @return ARGON2_OK if @memory is a valid pointer and memory is allocated
110
+ */
111
+ int allocate_memory(const argon2_context *context, uint8_t **memory,
112
+ size_t num, size_t size);
113
+
114
+ /*
115
+ * Frees memory at the given pointer, uses the appropriate deallocator as
116
+ * specified in the context. Also cleans the memory using clear_internal_memory.
117
+ * @param context argon2_context which specifies the deallocator
118
+ * @param memory pointer to buffer to be freed
119
+ * @param size the size in bytes for each element to be deallocated
120
+ * @param num the number of elements to be deallocated
121
+ */
122
+ void free_memory(const argon2_context *context, uint8_t *memory,
123
+ size_t num, size_t size);
124
+
125
+ /* Function that securely cleans the memory. This ignores any flags set
126
+ * regarding clearing memory. Usually one just calls clear_internal_memory.
127
+ * @param mem Pointer to the memory
128
+ * @param s Memory size in bytes
129
+ */
130
+ void secure_wipe_memory(void *v, size_t n);
131
+
132
+ /* Function that securely clears the memory if FLAG_clear_internal_memory is
133
+ * set. If the flag isn't set, this function does nothing.
134
+ * @param mem Pointer to the memory
135
+ * @param s Memory size in bytes
136
+ */
137
+ void clear_internal_memory(void *v, size_t n);
138
+
139
+ /*
140
+ * Computes absolute position of reference block in the lane following a skewed
141
+ * distribution and using a pseudo-random value as input
142
+ * @param instance Pointer to the current instance
143
+ * @param position Pointer to the current position
144
+ * @param pseudo_rand 32-bit pseudo-random value used to determine the position
145
+ * @param same_lane Indicates if the block will be taken from the current lane.
146
+ * If so we can reference the current segment
147
+ * @pre All pointers must be valid
148
+ */
149
+ uint32_t index_alpha(const argon2_instance_t *instance,
150
+ const argon2_position_t *position, uint32_t pseudo_rand,
151
+ int same_lane);
152
+
153
+ /*
154
+ * Function that validates all inputs against predefined restrictions and return
155
+ * an error code
156
+ * @param context Pointer to current Argon2 context
157
+ * @return ARGON2_OK if everything is all right, otherwise one of error codes
158
+ * (all defined in <argon2.h>
159
+ */
160
+ int validate_inputs(const argon2_context *context);
161
+
162
+ /*
163
+ * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
164
+ * password and secret if needed
165
+ * @param context Pointer to the Argon2 internal structure containing memory
166
+ * pointer, and parameters for time and space requirements.
167
+ * @param blockhash Buffer for pre-hashing digest
168
+ * @param type Argon2 type
169
+ * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
170
+ * allocated
171
+ */
172
+ void initial_hash(uint8_t *blockhash, argon2_context *context,
173
+ argon2_type type);
174
+
175
+ /*
176
+ * Function creates first 2 blocks per lane
177
+ * @param instance Pointer to the current instance
178
+ * @param blockhash Pointer to the pre-hashing digest
179
+ * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
180
+ */
181
+ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
182
+
183
+ /*
184
+ * Function allocates memory, hashes the inputs with Blake, and creates first
185
+ * two blocks. Returns the pointer to the main memory with 2 blocks per lane
186
+ * initialized
187
+ * @param context Pointer to the Argon2 internal structure containing memory
188
+ * pointer, and parameters for time and space requirements.
189
+ * @param instance Current Argon2 instance
190
+ * @return Zero if successful, -1 if memory failed to allocate. @context->state
191
+ * will be modified if successful.
192
+ */
193
+ int initialize(argon2_instance_t *instance, argon2_context *context);
194
+
195
+ /*
196
+ * XORing the last block of each lane, hashing it, making the tag. Deallocates
197
+ * the memory.
198
+ * @param context Pointer to current Argon2 context (use only the out parameters
199
+ * from it)
200
+ * @param instance Pointer to current instance of Argon2
201
+ * @pre instance->state must point to necessary amount of memory
202
+ * @pre context->out must point to outlen bytes of memory
203
+ * @pre if context->free_cbk is not NULL, it should point to a function that
204
+ * deallocates memory
205
+ */
206
+ void finalize(const argon2_context *context, argon2_instance_t *instance);
207
+
208
+ /*
209
+ * Function that fills the segment using previous segments also from other
210
+ * threads
211
+ * @param context current context
212
+ * @param instance Pointer to the current instance
213
+ * @param position Current position
214
+ * @pre all block pointers must be valid
215
+ */
216
+ void fill_segment(const argon2_instance_t *instance,
217
+ argon2_position_t position);
218
+
219
+ /*
220
+ * Function that fills the entire memory t_cost times based on the first two
221
+ * blocks in each lane
222
+ * @param instance Pointer to the current instance
223
+ * @return ARGON2_OK if successful, @context->state
224
+ */
225
+ int fill_memory_blocks(argon2_instance_t *instance);
226
+
227
+ #endif
@@ -0,0 +1,463 @@
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 <stdio.h>
19
+ #include <stdlib.h>
20
+ #include <string.h>
21
+ #include <limits.h>
22
+ #include "encoding.h"
23
+ #include "core.h"
24
+
25
+ /*
26
+ * Example code for a decoder and encoder of "hash strings", with Argon2
27
+ * parameters.
28
+ *
29
+ * This code comprises three sections:
30
+ *
31
+ * -- The first section contains generic Base64 encoding and decoding
32
+ * functions. It is conceptually applicable to any hash function
33
+ * implementation that uses Base64 to encode and decode parameters,
34
+ * salts and outputs. It could be made into a library, provided that
35
+ * the relevant functions are made public (non-static) and be given
36
+ * reasonable names to avoid collisions with other functions.
37
+ *
38
+ * -- The second section is specific to Argon2. It encodes and decodes
39
+ * the parameters, salts and outputs. It does not compute the hash
40
+ * itself.
41
+ *
42
+ * The code was originally written by Thomas Pornin <pornin@bolet.org>,
43
+ * to whom comments and remarks may be sent. It is released under what
44
+ * should amount to Public Domain or its closest equivalent; the
45
+ * following mantra is supposed to incarnate that fact with all the
46
+ * proper legal rituals:
47
+ *
48
+ * ---------------------------------------------------------------------
49
+ * This file is provided under the terms of Creative Commons CC0 1.0
50
+ * Public Domain Dedication. To the extent possible under law, the
51
+ * author (Thomas Pornin) has waived all copyright and related or
52
+ * neighboring rights to this file. This work is published from: Canada.
53
+ * ---------------------------------------------------------------------
54
+ *
55
+ * Copyright (c) 2015 Thomas Pornin
56
+ */
57
+
58
+ /* ==================================================================== */
59
+ /*
60
+ * Common code; could be shared between different hash functions.
61
+ *
62
+ * Note: the Base64 functions below assume that uppercase letters (resp.
63
+ * lowercase letters) have consecutive numerical codes, that fit on 8
64
+ * bits. All modern systems use ASCII-compatible charsets, where these
65
+ * properties are true. If you are stuck with a dinosaur of a system
66
+ * that still defaults to EBCDIC then you already have much bigger
67
+ * interoperability issues to deal with.
68
+ */
69
+
70
+ /*
71
+ * Some macros for constant-time comparisons. These work over values in
72
+ * the 0..255 range. Returned value is 0x00 on "false", 0xFF on "true".
73
+ */
74
+ #define EQ(x, y) ((((0U - ((unsigned)(x) ^ (unsigned)(y))) >> 8) & 0xFF) ^ 0xFF)
75
+ #define GT(x, y) ((((unsigned)(y) - (unsigned)(x)) >> 8) & 0xFF)
76
+ #define GE(x, y) (GT(y, x) ^ 0xFF)
77
+ #define LT(x, y) GT(y, x)
78
+ #define LE(x, y) GE(y, x)
79
+
80
+ /*
81
+ * Convert value x (0..63) to corresponding Base64 character.
82
+ */
83
+ static int b64_byte_to_char(unsigned x) {
84
+ return (LT(x, 26) & (x + 'A')) |
85
+ (GE(x, 26) & LT(x, 52) & (x + ('a' - 26))) |
86
+ (GE(x, 52) & LT(x, 62) & (x + ('0' - 52))) | (EQ(x, 62) & '+') |
87
+ (EQ(x, 63) & '/');
88
+ }
89
+
90
+ /*
91
+ * Convert character c to the corresponding 6-bit value. If character c
92
+ * is not a Base64 character, then 0xFF (255) is returned.
93
+ */
94
+ static unsigned b64_char_to_byte(int c) {
95
+ unsigned x;
96
+
97
+ x = (GE(c, 'A') & LE(c, 'Z') & (c - 'A')) |
98
+ (GE(c, 'a') & LE(c, 'z') & (c - ('a' - 26))) |
99
+ (GE(c, '0') & LE(c, '9') & (c - ('0' - 52))) | (EQ(c, '+') & 62) |
100
+ (EQ(c, '/') & 63);
101
+ return x | (EQ(x, 0) & (EQ(c, 'A') ^ 0xFF));
102
+ }
103
+
104
+ /*
105
+ * Convert some bytes to Base64. 'dst_len' is the length (in characters)
106
+ * of the output buffer 'dst'; if that buffer is not large enough to
107
+ * receive the result (including the terminating 0), then (size_t)-1
108
+ * is returned. Otherwise, the zero-terminated Base64 string is written
109
+ * in the buffer, and the output length (counted WITHOUT the terminating
110
+ * zero) is returned.
111
+ */
112
+ static size_t to_base64(char *dst, size_t dst_len, const void *src,
113
+ size_t src_len) {
114
+ size_t olen;
115
+ const unsigned char *buf;
116
+ unsigned acc, acc_len;
117
+
118
+ olen = (src_len / 3) << 2;
119
+ switch (src_len % 3) {
120
+ case 2:
121
+ olen++;
122
+ /* fall through */
123
+ case 1:
124
+ olen += 2;
125
+ break;
126
+ }
127
+ if (dst_len <= olen) {
128
+ return (size_t)-1;
129
+ }
130
+ acc = 0;
131
+ acc_len = 0;
132
+ buf = (const unsigned char *)src;
133
+ while (src_len-- > 0) {
134
+ acc = (acc << 8) + (*buf++);
135
+ acc_len += 8;
136
+ while (acc_len >= 6) {
137
+ acc_len -= 6;
138
+ *dst++ = (char)b64_byte_to_char((acc >> acc_len) & 0x3F);
139
+ }
140
+ }
141
+ if (acc_len > 0) {
142
+ *dst++ = (char)b64_byte_to_char((acc << (6 - acc_len)) & 0x3F);
143
+ }
144
+ *dst++ = 0;
145
+ return olen;
146
+ }
147
+
148
+ /*
149
+ * Decode Base64 chars into bytes. The '*dst_len' value must initially
150
+ * contain the length of the output buffer '*dst'; when the decoding
151
+ * ends, the actual number of decoded bytes is written back in
152
+ * '*dst_len'.
153
+ *
154
+ * Decoding stops when a non-Base64 character is encountered, or when
155
+ * the output buffer capacity is exceeded. If an error occurred (output
156
+ * buffer is too small, invalid last characters leading to unprocessed
157
+ * buffered bits), then NULL is returned; otherwise, the returned value
158
+ * points to the first non-Base64 character in the source stream, which
159
+ * may be the terminating zero.
160
+ */
161
+ static const char *from_base64(void *dst, size_t *dst_len, const char *src) {
162
+ size_t len;
163
+ unsigned char *buf;
164
+ unsigned acc, acc_len;
165
+
166
+ buf = (unsigned char *)dst;
167
+ len = 0;
168
+ acc = 0;
169
+ acc_len = 0;
170
+ for (;;) {
171
+ unsigned d;
172
+
173
+ d = b64_char_to_byte(*src);
174
+ if (d == 0xFF) {
175
+ break;
176
+ }
177
+ src++;
178
+ acc = (acc << 6) + d;
179
+ acc_len += 6;
180
+ if (acc_len >= 8) {
181
+ acc_len -= 8;
182
+ if ((len++) >= *dst_len) {
183
+ return NULL;
184
+ }
185
+ *buf++ = (acc >> acc_len) & 0xFF;
186
+ }
187
+ }
188
+
189
+ /*
190
+ * If the input length is equal to 1 modulo 4 (which is
191
+ * invalid), then there will remain 6 unprocessed bits;
192
+ * otherwise, only 0, 2 or 4 bits are buffered. The buffered
193
+ * bits must also all be zero.
194
+ */
195
+ if (acc_len > 4 || (acc & (((unsigned)1 << acc_len) - 1)) != 0) {
196
+ return NULL;
197
+ }
198
+ *dst_len = len;
199
+ return src;
200
+ }
201
+
202
+ /*
203
+ * Decode decimal integer from 'str'; the value is written in '*v'.
204
+ * Returned value is a pointer to the next non-decimal character in the
205
+ * string. If there is no digit at all, or the value encoding is not
206
+ * minimal (extra leading zeros), or the value does not fit in an
207
+ * 'unsigned long', then NULL is returned.
208
+ */
209
+ static const char *decode_decimal(const char *str, unsigned long *v) {
210
+ const char *orig;
211
+ unsigned long acc;
212
+
213
+ acc = 0;
214
+ for (orig = str;; str++) {
215
+ int c;
216
+
217
+ c = *str;
218
+ if (c < '0' || c > '9') {
219
+ break;
220
+ }
221
+ c -= '0';
222
+ if (acc > (ULONG_MAX / 10)) {
223
+ return NULL;
224
+ }
225
+ acc *= 10;
226
+ if ((unsigned long)c > (ULONG_MAX - acc)) {
227
+ return NULL;
228
+ }
229
+ acc += (unsigned long)c;
230
+ }
231
+ if (str == orig || (*orig == '0' && str != (orig + 1))) {
232
+ return NULL;
233
+ }
234
+ *v = acc;
235
+ return str;
236
+ }
237
+
238
+ /* ==================================================================== */
239
+ /*
240
+ * Code specific to Argon2.
241
+ *
242
+ * The code below applies the following format:
243
+ *
244
+ * $argon2<T>[$v=<num>]$m=<num>,t=<num>,p=<num>$<bin>$<bin>
245
+ *
246
+ * where <T> is either 'd', 'id', or 'i', <num> is a decimal integer (positive,
247
+ * fits in an 'unsigned long'), and <bin> is Base64-encoded data (no '=' padding
248
+ * characters, no newline or whitespace).
249
+ *
250
+ * The last two binary chunks (encoded in Base64) are, in that order,
251
+ * the salt and the output. Both are required. The binary salt length and the
252
+ * output length must be in the allowed ranges defined in argon2.h.
253
+ *
254
+ * The ctx struct must contain buffers large enough to hold the salt and pwd
255
+ * when it is fed into decode_string.
256
+ */
257
+
258
+ int decode_string(argon2_context *ctx, const char *str, argon2_type type) {
259
+
260
+ /* check for prefix */
261
+ #define CC(prefix) \
262
+ do { \
263
+ size_t cc_len = strlen(prefix); \
264
+ if (strncmp(str, prefix, cc_len) != 0) { \
265
+ return ARGON2_DECODING_FAIL; \
266
+ } \
267
+ str += cc_len; \
268
+ } while ((void)0, 0)
269
+
270
+ /* optional prefix checking with supplied code */
271
+ #define CC_opt(prefix, code) \
272
+ do { \
273
+ size_t cc_len = strlen(prefix); \
274
+ if (strncmp(str, prefix, cc_len) == 0) { \
275
+ str += cc_len; \
276
+ { code; } \
277
+ } \
278
+ } while ((void)0, 0)
279
+
280
+ /* Decoding prefix into decimal */
281
+ #define DECIMAL(x) \
282
+ do { \
283
+ unsigned long dec_x; \
284
+ str = decode_decimal(str, &dec_x); \
285
+ if (str == NULL) { \
286
+ return ARGON2_DECODING_FAIL; \
287
+ } \
288
+ (x) = dec_x; \
289
+ } while ((void)0, 0)
290
+
291
+
292
+ /* Decoding prefix into uint32_t decimal */
293
+ #define DECIMAL_U32(x) \
294
+ do { \
295
+ unsigned long dec_x; \
296
+ str = decode_decimal(str, &dec_x); \
297
+ if (str == NULL || dec_x > UINT32_MAX) { \
298
+ return ARGON2_DECODING_FAIL; \
299
+ } \
300
+ (x) = (uint32_t)dec_x; \
301
+ } while ((void)0, 0)
302
+
303
+
304
+ /* Decoding base64 into a binary buffer */
305
+ #define BIN(buf, max_len, len) \
306
+ do { \
307
+ size_t bin_len = (max_len); \
308
+ str = from_base64(buf, &bin_len, str); \
309
+ if (str == NULL || bin_len > UINT32_MAX) { \
310
+ return ARGON2_DECODING_FAIL; \
311
+ } \
312
+ (len) = (uint32_t)bin_len; \
313
+ } while ((void)0, 0)
314
+
315
+ size_t maxsaltlen = ctx->saltlen;
316
+ size_t maxoutlen = ctx->outlen;
317
+ int validation_result;
318
+ const char* type_string;
319
+
320
+ /* We should start with the argon2_type we are using */
321
+ type_string = argon2_type2string(type, 0);
322
+ if (!type_string) {
323
+ return ARGON2_INCORRECT_TYPE;
324
+ }
325
+
326
+ CC("$");
327
+ CC(type_string);
328
+
329
+ /* Reading the version number if the default is suppressed */
330
+ ctx->version = ARGON2_VERSION_10;
331
+ CC_opt("$v=", DECIMAL_U32(ctx->version));
332
+
333
+ CC("$m=");
334
+ DECIMAL_U32(ctx->m_cost);
335
+ CC(",t=");
336
+ DECIMAL_U32(ctx->t_cost);
337
+ CC(",p=");
338
+ DECIMAL_U32(ctx->lanes);
339
+ ctx->threads = ctx->lanes;
340
+
341
+ CC("$");
342
+ BIN(ctx->salt, maxsaltlen, ctx->saltlen);
343
+ CC("$");
344
+ BIN(ctx->out, maxoutlen, ctx->outlen);
345
+
346
+ /* The rest of the fields get the default values */
347
+ ctx->secret = NULL;
348
+ ctx->secretlen = 0;
349
+ ctx->ad = NULL;
350
+ ctx->adlen = 0;
351
+ ctx->allocate_cbk = NULL;
352
+ ctx->free_cbk = NULL;
353
+ ctx->flags = ARGON2_DEFAULT_FLAGS;
354
+
355
+ /* On return, must have valid context */
356
+ validation_result = validate_inputs(ctx);
357
+ if (validation_result != ARGON2_OK) {
358
+ return validation_result;
359
+ }
360
+
361
+ /* Can't have any additional characters */
362
+ if (*str == 0) {
363
+ return ARGON2_OK;
364
+ } else {
365
+ return ARGON2_DECODING_FAIL;
366
+ }
367
+ #undef CC
368
+ #undef CC_opt
369
+ #undef DECIMAL
370
+ #undef BIN
371
+ }
372
+
373
+ int encode_string(char *dst, size_t dst_len, argon2_context *ctx,
374
+ argon2_type type) {
375
+ #define SS(str) \
376
+ do { \
377
+ size_t pp_len = strlen(str); \
378
+ if (pp_len >= dst_len) { \
379
+ return ARGON2_ENCODING_FAIL; \
380
+ } \
381
+ memcpy(dst, str, pp_len + 1); \
382
+ dst += pp_len; \
383
+ dst_len -= pp_len; \
384
+ } while ((void)0, 0)
385
+
386
+ #define SX(x) \
387
+ do { \
388
+ char tmp[30]; \
389
+ sprintf(tmp, "%lu", (unsigned long)(x)); \
390
+ SS(tmp); \
391
+ } while ((void)0, 0)
392
+
393
+ #define SB(buf, len) \
394
+ do { \
395
+ size_t sb_len = to_base64(dst, dst_len, buf, len); \
396
+ if (sb_len == (size_t)-1) { \
397
+ return ARGON2_ENCODING_FAIL; \
398
+ } \
399
+ dst += sb_len; \
400
+ dst_len -= sb_len; \
401
+ } while ((void)0, 0)
402
+
403
+ const char* type_string = argon2_type2string(type, 0);
404
+ int validation_result = validate_inputs(ctx);
405
+
406
+ if (!type_string) {
407
+ return ARGON2_ENCODING_FAIL;
408
+ }
409
+
410
+ if (validation_result != ARGON2_OK) {
411
+ return validation_result;
412
+ }
413
+
414
+
415
+ SS("$");
416
+ SS(type_string);
417
+
418
+ SS("$v=");
419
+ SX(ctx->version);
420
+
421
+ SS("$m=");
422
+ SX(ctx->m_cost);
423
+ SS(",t=");
424
+ SX(ctx->t_cost);
425
+ SS(",p=");
426
+ SX(ctx->lanes);
427
+
428
+ SS("$");
429
+ SB(ctx->salt, ctx->saltlen);
430
+
431
+ SS("$");
432
+ SB(ctx->out, ctx->outlen);
433
+ return ARGON2_OK;
434
+
435
+ #undef SS
436
+ #undef SX
437
+ #undef SB
438
+ }
439
+
440
+ size_t b64len(uint32_t len) {
441
+ size_t olen = ((size_t)len / 3) << 2;
442
+
443
+ switch (len % 3) {
444
+ case 2:
445
+ olen++;
446
+ /* fall through */
447
+ case 1:
448
+ olen += 2;
449
+ break;
450
+ }
451
+
452
+ return olen;
453
+ }
454
+
455
+ size_t numlen(uint32_t num) {
456
+ size_t len = 1;
457
+ while (num >= 10) {
458
+ ++len;
459
+ num = num / 10;
460
+ }
461
+ return len;
462
+ }
463
+