1// SPDX-License-Identifier: CC0-1.0 2/* Based on libxcrypt v4.4.17-0-g6b110bc */ 3/* One way encryption based on the SHA512-based Unix crypt implementation. 4 * 5 * Written by Ulrich Drepper <drepper at redhat.com> in 2007 [1]. 6 * Modified by Zack Weinberg <zackw at panix.com> in 2017, 2018. 7 * Composed by Bj��rn Esser <besser82 at fedoraproject.org> in 2018. 8 * Modified by Bj��rn Esser <besser82 at fedoraproject.org> in 2020. 9 * Modified by Steffen Jaeckel <jaeckel-floss at eyet-services.de> in 2021 10 * for U-Boot, instead of using the global errno to use a static one 11 * inside this file. 12 * To the extent possible under law, the named authors have waived all 13 * copyright and related or neighboring rights to this work. 14 * 15 * See https://creativecommons.org/publicdomain/zero/1.0/ for further 16 * details. 17 * 18 * This file is a modified except from [2], lines 1403 up to 1676. 19 * 20 * [1] https://www.akkadia.org/drepper/sha-crypt.html 21 * [2] https://www.akkadia.org/drepper/SHA-crypt.txt 22 */ 23 24#include "crypt-port.h" 25#include "alg-sha512.h" 26 27#include <linux/errno.h> 28#include <stdio.h> 29#include <stdlib.h> 30 31#if INCLUDE_sha512crypt 32 33/* Define our magic string to mark salt for SHA512 "encryption" 34 replacement. */ 35static const char sha512_salt_prefix[] = "$6$"; 36 37/* Prefix for optional rounds specification. */ 38static const char sha512_rounds_prefix[] = "rounds="; 39 40/* Maximum salt string length. */ 41#define SALT_LEN_MAX 16 42/* Default number of rounds if not explicitly specified. */ 43#define ROUNDS_DEFAULT 5000 44/* Minimum number of rounds. */ 45#define ROUNDS_MIN 1000 46/* Maximum number of rounds. */ 47#define ROUNDS_MAX 999999999 48 49/* The maximum possible length of a SHA512-hashed password string, 50 including the terminating NUL character. Prefix (including its NUL) 51 + rounds tag ("rounds=$" = "rounds=\0") + strlen(ROUNDS_MAX) 52 + salt (up to SALT_LEN_MAX chars) + '$' + hash (86 chars). */ 53 54#define LENGTH_OF_NUMBER(n) (sizeof #n - 1) 55 56#define SHA512_HASH_LENGTH \ 57 (sizeof (sha512_salt_prefix) + sizeof (sha512_rounds_prefix) + \ 58 LENGTH_OF_NUMBER (ROUNDS_MAX) + SALT_LEN_MAX + 1 + 86) 59 60static_assert (SHA512_HASH_LENGTH <= CRYPT_OUTPUT_SIZE, 61 "CRYPT_OUTPUT_SIZE is too small for SHA512"); 62 63/* A sha512_buffer holds all of the sensitive intermediate data. */ 64struct sha512_buffer 65{ 66 SHA512_CTX ctx; 67 uint8_t result[64]; 68 uint8_t p_bytes[64]; 69 uint8_t s_bytes[64]; 70}; 71 72static_assert (sizeof (struct sha512_buffer) <= ALG_SPECIFIC_SIZE, 73 "ALG_SPECIFIC_SIZE is too small for SHA512"); 74 75 76/* Use this instead of including errno.h */ 77static int errno; 78 79void crypt_sha512crypt_rn(const char *phrase, size_t phr_size, 80 const char *setting, size_t ARG_UNUSED(set_size), 81 uint8_t *output, size_t out_size, void *scratch, 82 size_t scr_size); 83 84int crypt_sha512crypt_rn_wrapped(const char *phrase, size_t phr_size, 85 const char *setting, size_t set_size, 86 u8 *output, size_t out_size, void *scratch, 87 size_t scr_size) 88{ 89 errno = 0; 90 crypt_sha512crypt_rn(phrase, phr_size, setting, set_size, output, 91 out_size, scratch, scr_size); 92 return -errno; 93} 94 95/* Subroutine of _xcrypt_crypt_sha512crypt_rn: Feed CTX with LEN bytes of a 96 virtual byte sequence consisting of BLOCK repeated over and over 97 indefinitely. */ 98static void 99sha512_process_recycled_bytes (unsigned char block[64], size_t len, 100 SHA512_CTX *ctx) 101{ 102 size_t cnt; 103 for (cnt = len; cnt >= 64; cnt -= 64) 104 SHA512_Update (ctx, block, 64); 105 SHA512_Update (ctx, block, cnt); 106} 107 108void 109crypt_sha512crypt_rn (const char *phrase, size_t phr_size, 110 const char *setting, size_t ARG_UNUSED (set_size), 111 uint8_t *output, size_t out_size, 112 void *scratch, size_t scr_size) 113{ 114 /* This shouldn't ever happen, but... */ 115 if (out_size < SHA512_HASH_LENGTH 116 || scr_size < sizeof (struct sha512_buffer)) 117 { 118 errno = ERANGE; 119 return; 120 } 121 122 struct sha512_buffer *buf = scratch; 123 SHA512_CTX *ctx = &buf->ctx; 124 uint8_t *result = buf->result; 125 uint8_t *p_bytes = buf->p_bytes; 126 uint8_t *s_bytes = buf->s_bytes; 127 char *cp = (char *)output; 128 const char *salt = setting; 129 130 size_t salt_size; 131 size_t cnt; 132 /* Default number of rounds. */ 133 size_t rounds = ROUNDS_DEFAULT; 134 bool rounds_custom = false; 135 136 /* Find beginning of salt string. The prefix should normally always 137 be present. Just in case it is not. */ 138 if (strncmp (sha512_salt_prefix, salt, sizeof (sha512_salt_prefix) - 1) == 0) 139 /* Skip salt prefix. */ 140 salt += sizeof (sha512_salt_prefix) - 1; 141 142 if (strncmp (salt, sha512_rounds_prefix, sizeof (sha512_rounds_prefix) - 1) 143 == 0) 144 { 145 const char *num = salt + sizeof (sha512_rounds_prefix) - 1; 146 /* Do not allow an explicit setting of zero rounds, nor of the 147 default number of rounds, nor leading zeroes on the rounds. */ 148 if (!(*num >= '1' && *num <= '9')) 149 { 150 errno = EINVAL; 151 return; 152 } 153 154 errno = 0; 155 char *endp; 156 rounds = strtoul (num, &endp, 10); 157 if (endp == num || *endp != '$' 158 || rounds < ROUNDS_MIN 159 || rounds > ROUNDS_MAX 160 || errno) 161 { 162 errno = EINVAL; 163 return; 164 } 165 salt = endp + 1; 166 rounds_custom = true; 167 } 168 169 /* The salt ends at the next '$' or the end of the string. 170 Ensure ':' does not appear in the salt (it is used as a separator in /etc/passwd). 171 Also check for '\n', as in /etc/passwd the whole parameters of the user data must 172 be on a single line. */ 173 salt_size = strcspn (salt, "$:\n"); 174 if (!(salt[salt_size] == '$' || !salt[salt_size])) 175 { 176 errno = EINVAL; 177 return; 178 } 179 180 /* Ensure we do not use more salt than SALT_LEN_MAX. */ 181 if (salt_size > SALT_LEN_MAX) 182 salt_size = SALT_LEN_MAX; 183 184 /* Compute alternate SHA512 sum with input PHRASE, SALT, and PHRASE. The 185 final result will be added to the first context. */ 186 SHA512_Init (ctx); 187 188 /* Add phrase. */ 189 SHA512_Update (ctx, phrase, phr_size); 190 191 /* Add salt. */ 192 SHA512_Update (ctx, salt, salt_size); 193 194 /* Add phrase again. */ 195 SHA512_Update (ctx, phrase, phr_size); 196 197 /* Now get result of this (64 bytes) and add it to the other 198 context. */ 199 SHA512_Final (result, ctx); 200 201 /* Prepare for the real work. */ 202 SHA512_Init (ctx); 203 204 /* Add the phrase string. */ 205 SHA512_Update (ctx, phrase, phr_size); 206 207 /* The last part is the salt string. This must be at most 8 208 characters and it ends at the first `$' character (for 209 compatibility with existing implementations). */ 210 SHA512_Update (ctx, salt, salt_size); 211 212 /* Add for any character in the phrase one byte of the alternate sum. */ 213 for (cnt = phr_size; cnt > 64; cnt -= 64) 214 SHA512_Update (ctx, result, 64); 215 SHA512_Update (ctx, result, cnt); 216 217 /* Take the binary representation of the length of the phrase and for every 218 1 add the alternate sum, for every 0 the phrase. */ 219 for (cnt = phr_size; cnt > 0; cnt >>= 1) 220 if ((cnt & 1) != 0) 221 SHA512_Update (ctx, result, 64); 222 else 223 SHA512_Update (ctx, phrase, phr_size); 224 225 /* Create intermediate result. */ 226 SHA512_Final (result, ctx); 227 228 /* Start computation of P byte sequence. */ 229 SHA512_Init (ctx); 230 231 /* For every character in the password add the entire password. */ 232 for (cnt = 0; cnt < phr_size; ++cnt) 233 SHA512_Update (ctx, phrase, phr_size); 234 235 /* Finish the digest. */ 236 SHA512_Final (p_bytes, ctx); 237 238 /* Start computation of S byte sequence. */ 239 SHA512_Init (ctx); 240 241 /* For every character in the password add the entire password. */ 242 for (cnt = 0; cnt < (size_t) 16 + (size_t) result[0]; ++cnt) 243 SHA512_Update (ctx, salt, salt_size); 244 245 /* Finish the digest. */ 246 SHA512_Final (s_bytes, ctx); 247 248 /* Repeatedly run the collected hash value through SHA512 to burn 249 CPU cycles. */ 250 for (cnt = 0; cnt < rounds; ++cnt) 251 { 252 /* New context. */ 253 SHA512_Init (ctx); 254 255 /* Add phrase or last result. */ 256 if ((cnt & 1) != 0) 257 sha512_process_recycled_bytes (p_bytes, phr_size, ctx); 258 else 259 SHA512_Update (ctx, result, 64); 260 261 /* Add salt for numbers not divisible by 3. */ 262 if (cnt % 3 != 0) 263 sha512_process_recycled_bytes (s_bytes, salt_size, ctx); 264 265 /* Add phrase for numbers not divisible by 7. */ 266 if (cnt % 7 != 0) 267 sha512_process_recycled_bytes (p_bytes, phr_size, ctx); 268 269 /* Add phrase or last result. */ 270 if ((cnt & 1) != 0) 271 SHA512_Update (ctx, result, 64); 272 else 273 sha512_process_recycled_bytes (p_bytes, phr_size, ctx); 274 275 /* Create intermediate result. */ 276 SHA512_Final (result, ctx); 277 } 278 279 /* Now we can construct the result string. It consists of four 280 parts, one of which is optional. We already know that buflen is 281 at least sha512_hash_length, therefore none of the string bashing 282 below can overflow the buffer. */ 283 284 memcpy (cp, sha512_salt_prefix, sizeof (sha512_salt_prefix) - 1); 285 cp += sizeof (sha512_salt_prefix) - 1; 286 287 if (rounds_custom) 288 { 289 int n = snprintf (cp, 290 SHA512_HASH_LENGTH - (sizeof (sha512_salt_prefix) - 1), 291 "%s%zu$", sha512_rounds_prefix, rounds); 292 cp += n; 293 } 294 295 memcpy (cp, salt, salt_size); 296 cp += salt_size; 297 *cp++ = '$'; 298 299#define b64_from_24bit(B2, B1, B0, N) \ 300 do { \ 301 unsigned int w = ((((unsigned int)(B2)) << 16) | \ 302 (((unsigned int)(B1)) << 8) | \ 303 ((unsigned int)(B0))); \ 304 int n = (N); \ 305 while (n-- > 0) \ 306 { \ 307 *cp++ = b64t[w & 0x3f]; \ 308 w >>= 6; \ 309 } \ 310 } while (0) 311 312 b64_from_24bit (result[0], result[21], result[42], 4); 313 b64_from_24bit (result[22], result[43], result[1], 4); 314 b64_from_24bit (result[44], result[2], result[23], 4); 315 b64_from_24bit (result[3], result[24], result[45], 4); 316 b64_from_24bit (result[25], result[46], result[4], 4); 317 b64_from_24bit (result[47], result[5], result[26], 4); 318 b64_from_24bit (result[6], result[27], result[48], 4); 319 b64_from_24bit (result[28], result[49], result[7], 4); 320 b64_from_24bit (result[50], result[8], result[29], 4); 321 b64_from_24bit (result[9], result[30], result[51], 4); 322 b64_from_24bit (result[31], result[52], result[10], 4); 323 b64_from_24bit (result[53], result[11], result[32], 4); 324 b64_from_24bit (result[12], result[33], result[54], 4); 325 b64_from_24bit (result[34], result[55], result[13], 4); 326 b64_from_24bit (result[56], result[14], result[35], 4); 327 b64_from_24bit (result[15], result[36], result[57], 4); 328 b64_from_24bit (result[37], result[58], result[16], 4); 329 b64_from_24bit (result[59], result[17], result[38], 4); 330 b64_from_24bit (result[18], result[39], result[60], 4); 331 b64_from_24bit (result[40], result[61], result[19], 4); 332 b64_from_24bit (result[62], result[20], result[41], 4); 333 b64_from_24bit (0, 0, result[63], 2); 334 335 *cp = '\0'; 336} 337 338#ifndef NO_GENSALT 339 340void 341gensalt_sha512crypt_rn (unsigned long count, 342 const uint8_t *rbytes, size_t nrbytes, 343 uint8_t *output, size_t output_size) 344{ 345 gensalt_sha_rn ('6', SALT_LEN_MAX, ROUNDS_DEFAULT, ROUNDS_MIN, ROUNDS_MAX, 346 count, rbytes, nrbytes, output, output_size); 347} 348 349#endif 350 351#endif 352