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