1 /*- 2 * Copyright 2013 Alexander Peslyak 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted. 7 * 8 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 9 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 10 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 11 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 12 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 13 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 14 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 15 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 16 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 17 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 18 * SUCH DAMAGE. 19 */ 20 21 #include <stdint.h> 22 #include <string.h> 23 24 #include "crypto_pwhash_scryptsalsa208sha256.h" 25 #include "crypto_scrypt.h" 26 #include "private/common.h" 27 #include "runtime.h" 28 #include "utils.h" 29 30 static const char *const itoa64 = 31 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"; 32 33 static uint8_t * 34 encode64_uint32(uint8_t *dst, size_t dstlen, uint32_t src, uint32_t srcbits) 35 { 36 uint32_t bit; 37 38 for (bit = 0; bit < srcbits; bit += 6) { 39 if (dstlen < 1) { 40 return NULL; /* LCOV_EXCL_LINE */ 41 } 42 *dst++ = itoa64[src & 0x3f]; 43 dstlen--; 44 src >>= 6; 45 } 46 return dst; 47 } 48 49 static uint8_t * 50 encode64(uint8_t *dst, size_t dstlen, const uint8_t *src, size_t srclen) 51 { 52 size_t i; 53 54 for (i = 0; i < srclen;) { 55 uint8_t *dnext; 56 uint32_t value = 0, bits = 0; 57 58 do { 59 value |= (uint32_t) src[i++] << bits; 60 bits += 8; 61 } while (bits < 24 && i < srclen); 62 63 dnext = encode64_uint32(dst, dstlen, value, bits); 64 if (!dnext) { 65 return NULL; /* LCOV_EXCL_LINE */ 66 } 67 dstlen -= dnext - dst; 68 dst = dnext; 69 } 70 return dst; 71 } 72 73 static int 74 decode64_one(uint32_t *dst, uint8_t src) 75 { 76 const char *ptr = strchr(itoa64, src); 77 78 if (ptr) { 79 *dst = (uint32_t)(ptr - itoa64); 80 return 0; 81 } 82 *dst = 0; 83 84 return -1; 85 } 86 87 static const uint8_t * 88 decode64_uint32(uint32_t *dst, uint32_t dstbits, const uint8_t *src) 89 { 90 uint32_t bit; 91 uint32_t value; 92 93 value = 0; 94 for (bit = 0; bit < dstbits; bit += 6) { 95 uint32_t one; 96 if (decode64_one(&one, *src)) { 97 *dst = 0; 98 return NULL; 99 } 100 src++; 101 value |= one << bit; 102 } 103 *dst = value; 104 105 return src; 106 } 107 108 const uint8_t * 109 escrypt_parse_setting(const uint8_t *setting, 110 uint32_t *N_log2_p, uint32_t *r_p, uint32_t *p_p) 111 { 112 const uint8_t *src; 113 114 if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$') { 115 return NULL; 116 } 117 src = setting + 3; 118 119 if (decode64_one(N_log2_p, *src)) { 120 return NULL; 121 } 122 src++; 123 124 src = decode64_uint32(r_p, 30, src); 125 if (!src) { 126 return NULL; 127 } 128 129 src = decode64_uint32(p_p, 30, src); 130 if (!src) { 131 return NULL; 132 } 133 return src; 134 } 135 136 uint8_t * 137 escrypt_r(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen, 138 const uint8_t *setting, uint8_t *buf, size_t buflen) 139 { 140 uint8_t hash[crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES]; 141 escrypt_kdf_t escrypt_kdf; 142 const uint8_t *src; 143 const uint8_t *salt; 144 uint8_t *dst; 145 size_t prefixlen; 146 size_t saltlen; 147 size_t need; 148 uint64_t N; 149 uint32_t N_log2; 150 uint32_t r; 151 uint32_t p; 152 153 src = escrypt_parse_setting(setting, &N_log2, &r, &p); 154 if (!src) { 155 return NULL; 156 } 157 N = (uint64_t) 1 << N_log2; 158 prefixlen = src - setting; 159 160 salt = src; 161 src = (uint8_t *) strrchr((char *) salt, '$'); 162 if (src) { 163 saltlen = src - salt; 164 } else { 165 saltlen = strlen((char *) salt); 166 } 167 need = prefixlen + saltlen + 1 + 168 crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1; 169 if (need > buflen || need < saltlen) { 170 return NULL; 171 } 172 #ifdef HAVE_EMMINTRIN_H 173 escrypt_kdf = 174 sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse; 175 #else 176 escrypt_kdf = escrypt_kdf_nosse; 177 #endif 178 if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen, N, r, p, hash, 179 sizeof(hash))) { 180 return NULL; 181 } 182 dst = buf; 183 memcpy(dst, setting, prefixlen + saltlen); 184 dst += prefixlen + saltlen; 185 *dst++ = '$'; 186 187 dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash)); 188 sodium_memzero(hash, sizeof hash); 189 if (!dst || dst >= buf + buflen) { 190 return NULL; /* Can't happen LCOV_EXCL_LINE */ 191 } 192 *dst = 0; /* NUL termination */ 193 194 return buf; 195 } 196 197 uint8_t * 198 escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p, const uint8_t *src, 199 size_t srclen, uint8_t *buf, size_t buflen) 200 { 201 uint8_t *dst; 202 size_t prefixlen = 203 (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */); 204 size_t saltlen = BYTES2CHARS(srclen); 205 size_t need; 206 207 need = prefixlen + saltlen + 1; 208 if (need > buflen || need < saltlen || saltlen < srclen) { 209 return NULL; /* LCOV_EXCL_LINE */ 210 } 211 if (N_log2 > 63 || ((uint64_t) r * (uint64_t) p >= (1U << 30))) { 212 return NULL; /* LCOV_EXCL_LINE */ 213 } 214 dst = buf; 215 *dst++ = '$'; 216 *dst++ = '7'; 217 *dst++ = '$'; 218 219 *dst++ = itoa64[N_log2]; 220 221 dst = encode64_uint32(dst, buflen - (dst - buf), r, 30); 222 if (!dst) { 223 return NULL; /* Can't happen LCOV_EXCL_LINE */ 224 } 225 dst = encode64_uint32(dst, buflen - (dst - buf), p, 30); 226 if (!dst) { 227 return NULL; /* Can't happen LCOV_EXCL_LINE */ 228 } 229 dst = encode64(dst, buflen - (dst - buf), src, srclen); 230 if (!dst || dst >= buf + buflen) { 231 return NULL; /* Can't happen LCOV_EXCL_LINE */ 232 } 233 *dst = 0; /* NUL termination */ 234 235 return buf; 236 } 237 238 int 239 crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t *passwd, size_t passwdlen, 240 const uint8_t *salt, size_t saltlen, 241 uint64_t N, uint32_t r, uint32_t p, 242 uint8_t *buf, size_t buflen) 243 { 244 escrypt_kdf_t escrypt_kdf; 245 escrypt_local_t local; 246 int retval; 247 248 if (escrypt_init_local(&local)) { 249 return -1; /* LCOV_EXCL_LINE */ 250 } 251 #if defined(HAVE_EMMINTRIN_H) 252 escrypt_kdf = 253 sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse; 254 #else 255 escrypt_kdf = escrypt_kdf_nosse; 256 #endif 257 retval = escrypt_kdf(&local, passwd, passwdlen, salt, saltlen, N, r, p, buf, 258 buflen); 259 if (escrypt_free_local(&local)) { 260 return -1; /* LCOV_EXCL_LINE */ 261 } 262 return retval; 263 } 264