argon2id 0.8.0.rc1-x86-linux-musl

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,452 @@
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 <string.h>
19
+ #include <stdlib.h>
20
+ #include <stdio.h>
21
+
22
+ #include "argon2.h"
23
+ #include "encoding.h"
24
+ #include "core.h"
25
+
26
+ const char *argon2_type2string(argon2_type type, int uppercase) {
27
+ switch (type) {
28
+ case Argon2_d:
29
+ return uppercase ? "Argon2d" : "argon2d";
30
+ case Argon2_i:
31
+ return uppercase ? "Argon2i" : "argon2i";
32
+ case Argon2_id:
33
+ return uppercase ? "Argon2id" : "argon2id";
34
+ }
35
+
36
+ return NULL;
37
+ }
38
+
39
+ int argon2_ctx(argon2_context *context, argon2_type type) {
40
+ /* 1. Validate all inputs */
41
+ int result = validate_inputs(context);
42
+ uint32_t memory_blocks, segment_length;
43
+ argon2_instance_t instance;
44
+
45
+ if (ARGON2_OK != result) {
46
+ return result;
47
+ }
48
+
49
+ if (Argon2_d != type && Argon2_i != type && Argon2_id != type) {
50
+ return ARGON2_INCORRECT_TYPE;
51
+ }
52
+
53
+ /* 2. Align memory size */
54
+ /* Minimum memory_blocks = 8L blocks, where L is the number of lanes */
55
+ memory_blocks = context->m_cost;
56
+
57
+ if (memory_blocks < 2 * ARGON2_SYNC_POINTS * context->lanes) {
58
+ memory_blocks = 2 * ARGON2_SYNC_POINTS * context->lanes;
59
+ }
60
+
61
+ segment_length = memory_blocks / (context->lanes * ARGON2_SYNC_POINTS);
62
+ /* Ensure that all segments have equal length */
63
+ memory_blocks = segment_length * (context->lanes * ARGON2_SYNC_POINTS);
64
+
65
+ instance.version = context->version;
66
+ instance.memory = NULL;
67
+ instance.passes = context->t_cost;
68
+ instance.memory_blocks = memory_blocks;
69
+ instance.segment_length = segment_length;
70
+ instance.lane_length = segment_length * ARGON2_SYNC_POINTS;
71
+ instance.lanes = context->lanes;
72
+ instance.threads = context->threads;
73
+ instance.type = type;
74
+
75
+ if (instance.threads > instance.lanes) {
76
+ instance.threads = instance.lanes;
77
+ }
78
+
79
+ /* 3. Initialization: Hashing inputs, allocating memory, filling first
80
+ * blocks
81
+ */
82
+ result = initialize(&instance, context);
83
+
84
+ if (ARGON2_OK != result) {
85
+ return result;
86
+ }
87
+
88
+ /* 4. Filling memory */
89
+ result = fill_memory_blocks(&instance);
90
+
91
+ if (ARGON2_OK != result) {
92
+ return result;
93
+ }
94
+ /* 5. Finalization */
95
+ finalize(context, &instance);
96
+
97
+ return ARGON2_OK;
98
+ }
99
+
100
+ int argon2_hash(const uint32_t t_cost, const uint32_t m_cost,
101
+ const uint32_t parallelism, const void *pwd,
102
+ const size_t pwdlen, const void *salt, const size_t saltlen,
103
+ void *hash, const size_t hashlen, char *encoded,
104
+ const size_t encodedlen, argon2_type type,
105
+ const uint32_t version){
106
+
107
+ argon2_context context;
108
+ int result;
109
+ uint8_t *out;
110
+
111
+ if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
112
+ return ARGON2_PWD_TOO_LONG;
113
+ }
114
+
115
+ if (saltlen > ARGON2_MAX_SALT_LENGTH) {
116
+ return ARGON2_SALT_TOO_LONG;
117
+ }
118
+
119
+ if (hashlen > ARGON2_MAX_OUTLEN) {
120
+ return ARGON2_OUTPUT_TOO_LONG;
121
+ }
122
+
123
+ if (hashlen < ARGON2_MIN_OUTLEN) {
124
+ return ARGON2_OUTPUT_TOO_SHORT;
125
+ }
126
+
127
+ out = malloc(hashlen);
128
+ if (!out) {
129
+ return ARGON2_MEMORY_ALLOCATION_ERROR;
130
+ }
131
+
132
+ context.out = (uint8_t *)out;
133
+ context.outlen = (uint32_t)hashlen;
134
+ context.pwd = CONST_CAST(uint8_t *)pwd;
135
+ context.pwdlen = (uint32_t)pwdlen;
136
+ context.salt = CONST_CAST(uint8_t *)salt;
137
+ context.saltlen = (uint32_t)saltlen;
138
+ context.secret = NULL;
139
+ context.secretlen = 0;
140
+ context.ad = NULL;
141
+ context.adlen = 0;
142
+ context.t_cost = t_cost;
143
+ context.m_cost = m_cost;
144
+ context.lanes = parallelism;
145
+ context.threads = parallelism;
146
+ context.allocate_cbk = NULL;
147
+ context.free_cbk = NULL;
148
+ context.flags = ARGON2_DEFAULT_FLAGS;
149
+ context.version = version;
150
+
151
+ result = argon2_ctx(&context, type);
152
+
153
+ if (result != ARGON2_OK) {
154
+ clear_internal_memory(out, hashlen);
155
+ free(out);
156
+ return result;
157
+ }
158
+
159
+ /* if raw hash requested, write it */
160
+ if (hash) {
161
+ memcpy(hash, out, hashlen);
162
+ }
163
+
164
+ /* if encoding requested, write it */
165
+ if (encoded && encodedlen) {
166
+ if (encode_string(encoded, encodedlen, &context, type) != ARGON2_OK) {
167
+ clear_internal_memory(out, hashlen); /* wipe buffers if error */
168
+ clear_internal_memory(encoded, encodedlen);
169
+ free(out);
170
+ return ARGON2_ENCODING_FAIL;
171
+ }
172
+ }
173
+ clear_internal_memory(out, hashlen);
174
+ free(out);
175
+
176
+ return ARGON2_OK;
177
+ }
178
+
179
+ int argon2i_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
180
+ const uint32_t parallelism, const void *pwd,
181
+ const size_t pwdlen, const void *salt,
182
+ const size_t saltlen, const size_t hashlen,
183
+ char *encoded, const size_t encodedlen) {
184
+
185
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
186
+ NULL, hashlen, encoded, encodedlen, Argon2_i,
187
+ ARGON2_VERSION_NUMBER);
188
+ }
189
+
190
+ int argon2i_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
191
+ const uint32_t parallelism, const void *pwd,
192
+ const size_t pwdlen, const void *salt,
193
+ const size_t saltlen, void *hash, const size_t hashlen) {
194
+
195
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
196
+ hash, hashlen, NULL, 0, Argon2_i, ARGON2_VERSION_NUMBER);
197
+ }
198
+
199
+ int argon2d_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
200
+ const uint32_t parallelism, const void *pwd,
201
+ const size_t pwdlen, const void *salt,
202
+ const size_t saltlen, const size_t hashlen,
203
+ char *encoded, const size_t encodedlen) {
204
+
205
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
206
+ NULL, hashlen, encoded, encodedlen, Argon2_d,
207
+ ARGON2_VERSION_NUMBER);
208
+ }
209
+
210
+ int argon2d_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
211
+ const uint32_t parallelism, const void *pwd,
212
+ const size_t pwdlen, const void *salt,
213
+ const size_t saltlen, void *hash, const size_t hashlen) {
214
+
215
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
216
+ hash, hashlen, NULL, 0, Argon2_d, ARGON2_VERSION_NUMBER);
217
+ }
218
+
219
+ int argon2id_hash_encoded(const uint32_t t_cost, const uint32_t m_cost,
220
+ const uint32_t parallelism, const void *pwd,
221
+ const size_t pwdlen, const void *salt,
222
+ const size_t saltlen, const size_t hashlen,
223
+ char *encoded, const size_t encodedlen) {
224
+
225
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
226
+ NULL, hashlen, encoded, encodedlen, Argon2_id,
227
+ ARGON2_VERSION_NUMBER);
228
+ }
229
+
230
+ int argon2id_hash_raw(const uint32_t t_cost, const uint32_t m_cost,
231
+ const uint32_t parallelism, const void *pwd,
232
+ const size_t pwdlen, const void *salt,
233
+ const size_t saltlen, void *hash, const size_t hashlen) {
234
+ return argon2_hash(t_cost, m_cost, parallelism, pwd, pwdlen, salt, saltlen,
235
+ hash, hashlen, NULL, 0, Argon2_id,
236
+ ARGON2_VERSION_NUMBER);
237
+ }
238
+
239
+ static int argon2_compare(const uint8_t *b1, const uint8_t *b2, size_t len) {
240
+ size_t i;
241
+ uint8_t d = 0U;
242
+
243
+ for (i = 0U; i < len; i++) {
244
+ d |= b1[i] ^ b2[i];
245
+ }
246
+ return (int)((1 & ((d - 1) >> 8)) - 1);
247
+ }
248
+
249
+ int argon2_verify(const char *encoded, const void *pwd, const size_t pwdlen,
250
+ argon2_type type) {
251
+
252
+ argon2_context ctx;
253
+ uint8_t *desired_result = NULL;
254
+
255
+ int ret = ARGON2_OK;
256
+
257
+ size_t encoded_len;
258
+ uint32_t max_field_len;
259
+
260
+ if (pwdlen > ARGON2_MAX_PWD_LENGTH) {
261
+ return ARGON2_PWD_TOO_LONG;
262
+ }
263
+
264
+ if (encoded == NULL) {
265
+ return ARGON2_DECODING_FAIL;
266
+ }
267
+
268
+ encoded_len = strlen(encoded);
269
+ if (encoded_len > UINT32_MAX) {
270
+ return ARGON2_DECODING_FAIL;
271
+ }
272
+
273
+ /* No field can be longer than the encoded length */
274
+ max_field_len = (uint32_t)encoded_len;
275
+
276
+ ctx.saltlen = max_field_len;
277
+ ctx.outlen = max_field_len;
278
+
279
+ ctx.salt = malloc(ctx.saltlen);
280
+ ctx.out = malloc(ctx.outlen);
281
+ if (!ctx.salt || !ctx.out) {
282
+ ret = ARGON2_MEMORY_ALLOCATION_ERROR;
283
+ goto fail;
284
+ }
285
+
286
+ ctx.pwd = (uint8_t *)pwd;
287
+ ctx.pwdlen = (uint32_t)pwdlen;
288
+
289
+ ret = decode_string(&ctx, encoded, type);
290
+ if (ret != ARGON2_OK) {
291
+ goto fail;
292
+ }
293
+
294
+ /* Set aside the desired result, and get a new buffer. */
295
+ desired_result = ctx.out;
296
+ ctx.out = malloc(ctx.outlen);
297
+ if (!ctx.out) {
298
+ ret = ARGON2_MEMORY_ALLOCATION_ERROR;
299
+ goto fail;
300
+ }
301
+
302
+ ret = argon2_verify_ctx(&ctx, (char *)desired_result, type);
303
+ if (ret != ARGON2_OK) {
304
+ goto fail;
305
+ }
306
+
307
+ fail:
308
+ free(ctx.salt);
309
+ free(ctx.out);
310
+ free(desired_result);
311
+
312
+ return ret;
313
+ }
314
+
315
+ int argon2i_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
316
+
317
+ return argon2_verify(encoded, pwd, pwdlen, Argon2_i);
318
+ }
319
+
320
+ int argon2d_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
321
+
322
+ return argon2_verify(encoded, pwd, pwdlen, Argon2_d);
323
+ }
324
+
325
+ int argon2id_verify(const char *encoded, const void *pwd, const size_t pwdlen) {
326
+
327
+ return argon2_verify(encoded, pwd, pwdlen, Argon2_id);
328
+ }
329
+
330
+ int argon2d_ctx(argon2_context *context) {
331
+ return argon2_ctx(context, Argon2_d);
332
+ }
333
+
334
+ int argon2i_ctx(argon2_context *context) {
335
+ return argon2_ctx(context, Argon2_i);
336
+ }
337
+
338
+ int argon2id_ctx(argon2_context *context) {
339
+ return argon2_ctx(context, Argon2_id);
340
+ }
341
+
342
+ int argon2_verify_ctx(argon2_context *context, const char *hash,
343
+ argon2_type type) {
344
+ int ret = argon2_ctx(context, type);
345
+ if (ret != ARGON2_OK) {
346
+ return ret;
347
+ }
348
+
349
+ if (argon2_compare((uint8_t *)hash, context->out, context->outlen)) {
350
+ return ARGON2_VERIFY_MISMATCH;
351
+ }
352
+
353
+ return ARGON2_OK;
354
+ }
355
+
356
+ int argon2d_verify_ctx(argon2_context *context, const char *hash) {
357
+ return argon2_verify_ctx(context, hash, Argon2_d);
358
+ }
359
+
360
+ int argon2i_verify_ctx(argon2_context *context, const char *hash) {
361
+ return argon2_verify_ctx(context, hash, Argon2_i);
362
+ }
363
+
364
+ int argon2id_verify_ctx(argon2_context *context, const char *hash) {
365
+ return argon2_verify_ctx(context, hash, Argon2_id);
366
+ }
367
+
368
+ const char *argon2_error_message(int error_code) {
369
+ switch (error_code) {
370
+ case ARGON2_OK:
371
+ return "OK";
372
+ case ARGON2_OUTPUT_PTR_NULL:
373
+ return "Output pointer is NULL";
374
+ case ARGON2_OUTPUT_TOO_SHORT:
375
+ return "Output is too short";
376
+ case ARGON2_OUTPUT_TOO_LONG:
377
+ return "Output is too long";
378
+ case ARGON2_PWD_TOO_SHORT:
379
+ return "Password is too short";
380
+ case ARGON2_PWD_TOO_LONG:
381
+ return "Password is too long";
382
+ case ARGON2_SALT_TOO_SHORT:
383
+ return "Salt is too short";
384
+ case ARGON2_SALT_TOO_LONG:
385
+ return "Salt is too long";
386
+ case ARGON2_AD_TOO_SHORT:
387
+ return "Associated data is too short";
388
+ case ARGON2_AD_TOO_LONG:
389
+ return "Associated data is too long";
390
+ case ARGON2_SECRET_TOO_SHORT:
391
+ return "Secret is too short";
392
+ case ARGON2_SECRET_TOO_LONG:
393
+ return "Secret is too long";
394
+ case ARGON2_TIME_TOO_SMALL:
395
+ return "Time cost is too small";
396
+ case ARGON2_TIME_TOO_LARGE:
397
+ return "Time cost is too large";
398
+ case ARGON2_MEMORY_TOO_LITTLE:
399
+ return "Memory cost is too small";
400
+ case ARGON2_MEMORY_TOO_MUCH:
401
+ return "Memory cost is too large";
402
+ case ARGON2_LANES_TOO_FEW:
403
+ return "Too few lanes";
404
+ case ARGON2_LANES_TOO_MANY:
405
+ return "Too many lanes";
406
+ case ARGON2_PWD_PTR_MISMATCH:
407
+ return "Password pointer is NULL, but password length is not 0";
408
+ case ARGON2_SALT_PTR_MISMATCH:
409
+ return "Salt pointer is NULL, but salt length is not 0";
410
+ case ARGON2_SECRET_PTR_MISMATCH:
411
+ return "Secret pointer is NULL, but secret length is not 0";
412
+ case ARGON2_AD_PTR_MISMATCH:
413
+ return "Associated data pointer is NULL, but ad length is not 0";
414
+ case ARGON2_MEMORY_ALLOCATION_ERROR:
415
+ return "Memory allocation error";
416
+ case ARGON2_FREE_MEMORY_CBK_NULL:
417
+ return "The free memory callback is NULL";
418
+ case ARGON2_ALLOCATE_MEMORY_CBK_NULL:
419
+ return "The allocate memory callback is NULL";
420
+ case ARGON2_INCORRECT_PARAMETER:
421
+ return "Argon2_Context context is NULL";
422
+ case ARGON2_INCORRECT_TYPE:
423
+ return "There is no such version of Argon2";
424
+ case ARGON2_OUT_PTR_MISMATCH:
425
+ return "Output pointer mismatch";
426
+ case ARGON2_THREADS_TOO_FEW:
427
+ return "Not enough threads";
428
+ case ARGON2_THREADS_TOO_MANY:
429
+ return "Too many threads";
430
+ case ARGON2_MISSING_ARGS:
431
+ return "Missing arguments";
432
+ case ARGON2_ENCODING_FAIL:
433
+ return "Encoding failed";
434
+ case ARGON2_DECODING_FAIL:
435
+ return "Decoding failed";
436
+ case ARGON2_THREAD_FAIL:
437
+ return "Threading failure";
438
+ case ARGON2_DECODING_LENGTH_FAIL:
439
+ return "Some of encoded parameters are too long or too short";
440
+ case ARGON2_VERIFY_MISMATCH:
441
+ return "The password does not match the supplied hash";
442
+ default:
443
+ return "Unknown error code";
444
+ }
445
+ }
446
+
447
+ size_t argon2_encodedlen(uint32_t t_cost, uint32_t m_cost, uint32_t parallelism,
448
+ uint32_t saltlen, uint32_t hashlen, argon2_type type) {
449
+ return strlen("$$v=$m=,t=,p=$$") + strlen(argon2_type2string(type, 0)) +
450
+ numlen(t_cost) + numlen(m_cost) + numlen(parallelism) +
451
+ b64len(saltlen) + b64len(hashlen) + numlen(ARGON2_VERSION_NUMBER) + 1;
452
+ }