argon2id 0.8.0.rc1-x86_64-linux-gnu

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.
@@ -0,0 +1,228 @@
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
+ ARGON2_512BIT_WORDS_IN_BLOCK = ARGON2_BLOCK_SIZE / 64,
34
+
35
+ /* Number of pseudo-random values generated by one call to Blake in Argon2i
36
+ to
37
+ generate reference block positions */
38
+ ARGON2_ADDRESSES_IN_BLOCK = 128,
39
+
40
+ /* Pre-hashing digest length and its extension*/
41
+ ARGON2_PREHASH_DIGEST_LENGTH = 64,
42
+ ARGON2_PREHASH_SEED_LENGTH = 72
43
+ };
44
+
45
+ /*************************Argon2 internal data types***********************/
46
+
47
+ /*
48
+ * Structure for the (1KB) memory block implemented as 128 64-bit words.
49
+ * Memory blocks can be copied, XORed. Internal words can be accessed by [] (no
50
+ * bounds checking).
51
+ */
52
+ typedef struct block_ { uint64_t v[ARGON2_QWORDS_IN_BLOCK]; } block;
53
+
54
+ /*****************Functions that work with the block******************/
55
+
56
+ /* Initialize each byte of the block with @in */
57
+ void init_block_value(block *b, uint8_t in);
58
+
59
+ /* Copy block @src to block @dst */
60
+ void copy_block(block *dst, const block *src);
61
+
62
+ /* XOR @src onto @dst bytewise */
63
+ void xor_block(block *dst, const block *src);
64
+
65
+ /*
66
+ * Argon2 instance: memory pointer, number of passes, amount of memory, type,
67
+ * and derived values.
68
+ * Used to evaluate the number and location of blocks to construct in each
69
+ * thread
70
+ */
71
+ typedef struct Argon2_instance_t {
72
+ block *memory; /* Memory pointer */
73
+ uint32_t version;
74
+ uint32_t passes; /* Number of passes */
75
+ uint32_t memory_blocks; /* Number of blocks in memory */
76
+ uint32_t segment_length;
77
+ uint32_t lane_length;
78
+ uint32_t lanes;
79
+ uint32_t threads;
80
+ argon2_type type;
81
+ int print_internals; /* whether to print the memory blocks */
82
+ argon2_context *context_ptr; /* points back to original context */
83
+ } argon2_instance_t;
84
+
85
+ /*
86
+ * Argon2 position: where we construct the block right now. Used to distribute
87
+ * work between threads.
88
+ */
89
+ typedef struct Argon2_position_t {
90
+ uint32_t pass;
91
+ uint32_t lane;
92
+ uint8_t slice;
93
+ uint32_t index;
94
+ } argon2_position_t;
95
+
96
+ /*Struct that holds the inputs for thread handling FillSegment*/
97
+ typedef struct Argon2_thread_data {
98
+ argon2_instance_t *instance_ptr;
99
+ argon2_position_t pos;
100
+ } argon2_thread_data;
101
+
102
+ /*************************Argon2 core functions********************************/
103
+
104
+ /* Allocates memory to the given pointer, uses the appropriate allocator as
105
+ * specified in the context. Total allocated memory is num*size.
106
+ * @param context argon2_context which specifies the allocator
107
+ * @param memory pointer to the pointer to the memory
108
+ * @param size the size in bytes for each element to be allocated
109
+ * @param num the number of elements to be allocated
110
+ * @return ARGON2_OK if @memory is a valid pointer and memory is allocated
111
+ */
112
+ int allocate_memory(const argon2_context *context, uint8_t **memory,
113
+ size_t num, size_t size);
114
+
115
+ /*
116
+ * Frees memory at the given pointer, uses the appropriate deallocator as
117
+ * specified in the context. Also cleans the memory using clear_internal_memory.
118
+ * @param context argon2_context which specifies the deallocator
119
+ * @param memory pointer to buffer to be freed
120
+ * @param size the size in bytes for each element to be deallocated
121
+ * @param num the number of elements to be deallocated
122
+ */
123
+ void free_memory(const argon2_context *context, uint8_t *memory,
124
+ size_t num, size_t size);
125
+
126
+ /* Function that securely cleans the memory. This ignores any flags set
127
+ * regarding clearing memory. Usually one just calls clear_internal_memory.
128
+ * @param mem Pointer to the memory
129
+ * @param s Memory size in bytes
130
+ */
131
+ void secure_wipe_memory(void *v, size_t n);
132
+
133
+ /* Function that securely clears the memory if FLAG_clear_internal_memory is
134
+ * set. If the flag isn't set, this function does nothing.
135
+ * @param mem Pointer to the memory
136
+ * @param s Memory size in bytes
137
+ */
138
+ void clear_internal_memory(void *v, size_t n);
139
+
140
+ /*
141
+ * Computes absolute position of reference block in the lane following a skewed
142
+ * distribution and using a pseudo-random value as input
143
+ * @param instance Pointer to the current instance
144
+ * @param position Pointer to the current position
145
+ * @param pseudo_rand 32-bit pseudo-random value used to determine the position
146
+ * @param same_lane Indicates if the block will be taken from the current lane.
147
+ * If so we can reference the current segment
148
+ * @pre All pointers must be valid
149
+ */
150
+ uint32_t index_alpha(const argon2_instance_t *instance,
151
+ const argon2_position_t *position, uint32_t pseudo_rand,
152
+ int same_lane);
153
+
154
+ /*
155
+ * Function that validates all inputs against predefined restrictions and return
156
+ * an error code
157
+ * @param context Pointer to current Argon2 context
158
+ * @return ARGON2_OK if everything is all right, otherwise one of error codes
159
+ * (all defined in <argon2.h>
160
+ */
161
+ int validate_inputs(const argon2_context *context);
162
+
163
+ /*
164
+ * Hashes all the inputs into @a blockhash[PREHASH_DIGEST_LENGTH], clears
165
+ * password and secret if needed
166
+ * @param context Pointer to the Argon2 internal structure containing memory
167
+ * pointer, and parameters for time and space requirements.
168
+ * @param blockhash Buffer for pre-hashing digest
169
+ * @param type Argon2 type
170
+ * @pre @a blockhash must have at least @a PREHASH_DIGEST_LENGTH bytes
171
+ * allocated
172
+ */
173
+ void initial_hash(uint8_t *blockhash, argon2_context *context,
174
+ argon2_type type);
175
+
176
+ /*
177
+ * Function creates first 2 blocks per lane
178
+ * @param instance Pointer to the current instance
179
+ * @param blockhash Pointer to the pre-hashing digest
180
+ * @pre blockhash must point to @a PREHASH_SEED_LENGTH allocated values
181
+ */
182
+ void fill_first_blocks(uint8_t *blockhash, const argon2_instance_t *instance);
183
+
184
+ /*
185
+ * Function allocates memory, hashes the inputs with Blake, and creates first
186
+ * two blocks. Returns the pointer to the main memory with 2 blocks per lane
187
+ * initialized
188
+ * @param context Pointer to the Argon2 internal structure containing memory
189
+ * pointer, and parameters for time and space requirements.
190
+ * @param instance Current Argon2 instance
191
+ * @return Zero if successful, -1 if memory failed to allocate. @context->state
192
+ * will be modified if successful.
193
+ */
194
+ int initialize(argon2_instance_t *instance, argon2_context *context);
195
+
196
+ /*
197
+ * XORing the last block of each lane, hashing it, making the tag. Deallocates
198
+ * the memory.
199
+ * @param context Pointer to current Argon2 context (use only the out parameters
200
+ * from it)
201
+ * @param instance Pointer to current instance of Argon2
202
+ * @pre instance->state must point to necessary amount of memory
203
+ * @pre context->out must point to outlen bytes of memory
204
+ * @pre if context->free_cbk is not NULL, it should point to a function that
205
+ * deallocates memory
206
+ */
207
+ void finalize(const argon2_context *context, argon2_instance_t *instance);
208
+
209
+ /*
210
+ * Function that fills the segment using previous segments also from other
211
+ * threads
212
+ * @param context current context
213
+ * @param instance Pointer to the current instance
214
+ * @param position Current position
215
+ * @pre all block pointers must be valid
216
+ */
217
+ void fill_segment(const argon2_instance_t *instance,
218
+ argon2_position_t position);
219
+
220
+ /*
221
+ * Function that fills the entire memory t_cost times based on the first two
222
+ * blocks in each lane
223
+ * @param instance Pointer to the current instance
224
+ * @return ARGON2_OK if successful, @context->state
225
+ */
226
+ int fill_memory_blocks(argon2_instance_t *instance);
227
+
228
+ #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
+