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 464