"Fossies" - the Fresh Open Source Software Archive 
Member "cryptsetup-2.4.3/lib/crypto_backend/argon2/encoding.c" (13 Jan 2022, 16268 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 "encoding.c" see the
Fossies "Dox" file reference documentation.
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 <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 }