10ac341f1SConrad Meyer /*-
20ac341f1SConrad Meyer  * Copyright 2013 Alexander Peslyak
30ac341f1SConrad Meyer  * All rights reserved.
40ac341f1SConrad Meyer  *
50ac341f1SConrad Meyer  * Redistribution and use in source and binary forms, with or without
60ac341f1SConrad Meyer  * modification, are permitted.
70ac341f1SConrad Meyer  *
80ac341f1SConrad Meyer  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
90ac341f1SConrad Meyer  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
100ac341f1SConrad Meyer  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
110ac341f1SConrad Meyer  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
120ac341f1SConrad Meyer  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
130ac341f1SConrad Meyer  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
140ac341f1SConrad Meyer  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
150ac341f1SConrad Meyer  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
160ac341f1SConrad Meyer  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
170ac341f1SConrad Meyer  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
180ac341f1SConrad Meyer  * SUCH DAMAGE.
190ac341f1SConrad Meyer  */
200ac341f1SConrad Meyer 
210ac341f1SConrad Meyer #include <stdint.h>
220ac341f1SConrad Meyer #include <string.h>
230ac341f1SConrad Meyer 
240ac341f1SConrad Meyer #include "crypto_pwhash_scryptsalsa208sha256.h"
250ac341f1SConrad Meyer #include "crypto_scrypt.h"
260ac341f1SConrad Meyer #include "private/common.h"
270ac341f1SConrad Meyer #include "runtime.h"
280ac341f1SConrad Meyer #include "utils.h"
290ac341f1SConrad Meyer 
300ac341f1SConrad Meyer static const char *const itoa64 =
310ac341f1SConrad Meyer     "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
320ac341f1SConrad Meyer 
330ac341f1SConrad Meyer static uint8_t *
encode64_uint32(uint8_t * dst,size_t dstlen,uint32_t src,uint32_t srcbits)340ac341f1SConrad Meyer encode64_uint32(uint8_t *dst, size_t dstlen, uint32_t src, uint32_t srcbits)
350ac341f1SConrad Meyer {
360ac341f1SConrad Meyer     uint32_t bit;
370ac341f1SConrad Meyer 
380ac341f1SConrad Meyer     for (bit = 0; bit < srcbits; bit += 6) {
390ac341f1SConrad Meyer         if (dstlen < 1) {
400ac341f1SConrad Meyer             return NULL; /* LCOV_EXCL_LINE */
410ac341f1SConrad Meyer         }
420ac341f1SConrad Meyer         *dst++ = itoa64[src & 0x3f];
430ac341f1SConrad Meyer         dstlen--;
440ac341f1SConrad Meyer         src >>= 6;
450ac341f1SConrad Meyer     }
460ac341f1SConrad Meyer     return dst;
470ac341f1SConrad Meyer }
480ac341f1SConrad Meyer 
490ac341f1SConrad Meyer static uint8_t *
encode64(uint8_t * dst,size_t dstlen,const uint8_t * src,size_t srclen)500ac341f1SConrad Meyer encode64(uint8_t *dst, size_t dstlen, const uint8_t *src, size_t srclen)
510ac341f1SConrad Meyer {
520ac341f1SConrad Meyer     size_t i;
530ac341f1SConrad Meyer 
540ac341f1SConrad Meyer     for (i = 0; i < srclen;) {
550ac341f1SConrad Meyer         uint8_t *dnext;
560ac341f1SConrad Meyer         uint32_t value = 0, bits = 0;
570ac341f1SConrad Meyer 
580ac341f1SConrad Meyer         do {
590ac341f1SConrad Meyer             value |= (uint32_t) src[i++] << bits;
600ac341f1SConrad Meyer             bits += 8;
610ac341f1SConrad Meyer         } while (bits < 24 && i < srclen);
620ac341f1SConrad Meyer 
630ac341f1SConrad Meyer         dnext = encode64_uint32(dst, dstlen, value, bits);
640ac341f1SConrad Meyer         if (!dnext) {
650ac341f1SConrad Meyer             return NULL; /* LCOV_EXCL_LINE */
660ac341f1SConrad Meyer         }
670ac341f1SConrad Meyer         dstlen -= dnext - dst;
680ac341f1SConrad Meyer         dst = dnext;
690ac341f1SConrad Meyer     }
700ac341f1SConrad Meyer     return dst;
710ac341f1SConrad Meyer }
720ac341f1SConrad Meyer 
730ac341f1SConrad Meyer static int
decode64_one(uint32_t * dst,uint8_t src)740ac341f1SConrad Meyer decode64_one(uint32_t *dst, uint8_t src)
750ac341f1SConrad Meyer {
760ac341f1SConrad Meyer     const char *ptr = strchr(itoa64, src);
770ac341f1SConrad Meyer 
780ac341f1SConrad Meyer     if (ptr) {
790ac341f1SConrad Meyer         *dst = (uint32_t)(ptr - itoa64);
800ac341f1SConrad Meyer         return 0;
810ac341f1SConrad Meyer     }
820ac341f1SConrad Meyer     *dst = 0;
830ac341f1SConrad Meyer 
840ac341f1SConrad Meyer     return -1;
850ac341f1SConrad Meyer }
860ac341f1SConrad Meyer 
870ac341f1SConrad Meyer static const uint8_t *
decode64_uint32(uint32_t * dst,uint32_t dstbits,const uint8_t * src)880ac341f1SConrad Meyer decode64_uint32(uint32_t *dst, uint32_t dstbits, const uint8_t *src)
890ac341f1SConrad Meyer {
900ac341f1SConrad Meyer     uint32_t bit;
910ac341f1SConrad Meyer     uint32_t value;
920ac341f1SConrad Meyer 
930ac341f1SConrad Meyer     value = 0;
940ac341f1SConrad Meyer     for (bit = 0; bit < dstbits; bit += 6) {
950ac341f1SConrad Meyer         uint32_t one;
960ac341f1SConrad Meyer         if (decode64_one(&one, *src)) {
970ac341f1SConrad Meyer             *dst = 0;
980ac341f1SConrad Meyer             return NULL;
990ac341f1SConrad Meyer         }
1000ac341f1SConrad Meyer         src++;
1010ac341f1SConrad Meyer         value |= one << bit;
1020ac341f1SConrad Meyer     }
1030ac341f1SConrad Meyer     *dst = value;
1040ac341f1SConrad Meyer 
1050ac341f1SConrad Meyer     return src;
1060ac341f1SConrad Meyer }
1070ac341f1SConrad Meyer 
1080ac341f1SConrad Meyer const uint8_t *
escrypt_parse_setting(const uint8_t * setting,uint32_t * N_log2_p,uint32_t * r_p,uint32_t * p_p)1090ac341f1SConrad Meyer escrypt_parse_setting(const uint8_t *setting,
1100ac341f1SConrad Meyer                       uint32_t *N_log2_p, uint32_t *r_p, uint32_t *p_p)
1110ac341f1SConrad Meyer {
1120ac341f1SConrad Meyer     const uint8_t *src;
1130ac341f1SConrad Meyer 
1140ac341f1SConrad Meyer     if (setting[0] != '$' || setting[1] != '7' || setting[2] != '$') {
1150ac341f1SConrad Meyer         return NULL;
1160ac341f1SConrad Meyer     }
1170ac341f1SConrad Meyer     src = setting + 3;
1180ac341f1SConrad Meyer 
1190ac341f1SConrad Meyer     if (decode64_one(N_log2_p, *src)) {
1200ac341f1SConrad Meyer         return NULL;
1210ac341f1SConrad Meyer     }
1220ac341f1SConrad Meyer     src++;
1230ac341f1SConrad Meyer 
1240ac341f1SConrad Meyer     src = decode64_uint32(r_p, 30, src);
1250ac341f1SConrad Meyer     if (!src) {
1260ac341f1SConrad Meyer         return NULL;
1270ac341f1SConrad Meyer     }
1280ac341f1SConrad Meyer 
1290ac341f1SConrad Meyer     src = decode64_uint32(p_p, 30, src);
1300ac341f1SConrad Meyer     if (!src) {
1310ac341f1SConrad Meyer         return NULL;
1320ac341f1SConrad Meyer     }
1330ac341f1SConrad Meyer     return src;
1340ac341f1SConrad Meyer }
1350ac341f1SConrad Meyer 
1360ac341f1SConrad Meyer uint8_t *
escrypt_r(escrypt_local_t * local,const uint8_t * passwd,size_t passwdlen,const uint8_t * setting,uint8_t * buf,size_t buflen)1370ac341f1SConrad Meyer escrypt_r(escrypt_local_t *local, const uint8_t *passwd, size_t passwdlen,
1380ac341f1SConrad Meyer           const uint8_t *setting, uint8_t *buf, size_t buflen)
1390ac341f1SConrad Meyer {
1400ac341f1SConrad Meyer     uint8_t        hash[crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES];
1410ac341f1SConrad Meyer     escrypt_kdf_t  escrypt_kdf;
1420ac341f1SConrad Meyer     const uint8_t *src;
1430ac341f1SConrad Meyer     const uint8_t *salt;
1440ac341f1SConrad Meyer     uint8_t       *dst;
1450ac341f1SConrad Meyer     size_t         prefixlen;
1460ac341f1SConrad Meyer     size_t         saltlen;
1470ac341f1SConrad Meyer     size_t         need;
1480ac341f1SConrad Meyer     uint64_t       N;
1490ac341f1SConrad Meyer     uint32_t       N_log2;
1500ac341f1SConrad Meyer     uint32_t       r;
1510ac341f1SConrad Meyer     uint32_t       p;
1520ac341f1SConrad Meyer 
1530ac341f1SConrad Meyer     src = escrypt_parse_setting(setting, &N_log2, &r, &p);
1540ac341f1SConrad Meyer     if (!src) {
1550ac341f1SConrad Meyer         return NULL;
1560ac341f1SConrad Meyer     }
1570ac341f1SConrad Meyer     N = (uint64_t) 1 << N_log2;
1580ac341f1SConrad Meyer     prefixlen = src - setting;
1590ac341f1SConrad Meyer 
1600ac341f1SConrad Meyer     salt = src;
1610ac341f1SConrad Meyer     src  = (uint8_t *) strrchr((char *) salt, '$');
1620ac341f1SConrad Meyer     if (src) {
1630ac341f1SConrad Meyer         saltlen = src - salt;
1640ac341f1SConrad Meyer     } else {
1650ac341f1SConrad Meyer         saltlen = strlen((char *) salt);
1660ac341f1SConrad Meyer     }
1670ac341f1SConrad Meyer     need = prefixlen + saltlen + 1 +
1680ac341f1SConrad Meyer            crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1;
1690ac341f1SConrad Meyer     if (need > buflen || need < saltlen) {
1700ac341f1SConrad Meyer         return NULL;
1710ac341f1SConrad Meyer     }
1720ac341f1SConrad Meyer #ifdef HAVE_EMMINTRIN_H
1730ac341f1SConrad Meyer     escrypt_kdf =
1740ac341f1SConrad Meyer         sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
1750ac341f1SConrad Meyer #else
1760ac341f1SConrad Meyer     escrypt_kdf = escrypt_kdf_nosse;
1770ac341f1SConrad Meyer #endif
1780ac341f1SConrad Meyer     if (escrypt_kdf(local, passwd, passwdlen, salt, saltlen, N, r, p, hash,
1790ac341f1SConrad Meyer                     sizeof(hash))) {
1800ac341f1SConrad Meyer         return NULL;
1810ac341f1SConrad Meyer     }
1820ac341f1SConrad Meyer     dst = buf;
1830ac341f1SConrad Meyer     memcpy(dst, setting, prefixlen + saltlen);
1840ac341f1SConrad Meyer     dst += prefixlen + saltlen;
1850ac341f1SConrad Meyer     *dst++ = '$';
1860ac341f1SConrad Meyer 
1870ac341f1SConrad Meyer     dst = encode64(dst, buflen - (dst - buf), hash, sizeof(hash));
1880ac341f1SConrad Meyer     sodium_memzero(hash, sizeof hash);
1890ac341f1SConrad Meyer     if (!dst || dst >= buf + buflen) {
1900ac341f1SConrad Meyer         return NULL; /* Can't happen LCOV_EXCL_LINE */
1910ac341f1SConrad Meyer     }
1920ac341f1SConrad Meyer     *dst = 0; /* NUL termination */
1930ac341f1SConrad Meyer 
1940ac341f1SConrad Meyer     return buf;
1950ac341f1SConrad Meyer }
1960ac341f1SConrad Meyer 
1970ac341f1SConrad Meyer uint8_t *
escrypt_gensalt_r(uint32_t N_log2,uint32_t r,uint32_t p,const uint8_t * src,size_t srclen,uint8_t * buf,size_t buflen)1980ac341f1SConrad Meyer escrypt_gensalt_r(uint32_t N_log2, uint32_t r, uint32_t p, const uint8_t *src,
1990ac341f1SConrad Meyer                   size_t srclen, uint8_t *buf, size_t buflen)
2000ac341f1SConrad Meyer {
2010ac341f1SConrad Meyer     uint8_t *dst;
2020ac341f1SConrad Meyer     size_t   prefixlen =
2030ac341f1SConrad Meyer         (sizeof "$7$" - 1U) + (1U /* N_log2 */) + (5U /* r */) + (5U /* p */);
2040ac341f1SConrad Meyer     size_t saltlen = BYTES2CHARS(srclen);
2050ac341f1SConrad Meyer     size_t need;
2060ac341f1SConrad Meyer 
2070ac341f1SConrad Meyer     need = prefixlen + saltlen + 1;
2080ac341f1SConrad Meyer     if (need > buflen || need < saltlen || saltlen < srclen) {
2090ac341f1SConrad Meyer         return NULL; /* LCOV_EXCL_LINE */
2100ac341f1SConrad Meyer     }
2110ac341f1SConrad Meyer     if (N_log2 > 63 || ((uint64_t) r * (uint64_t) p >= (1U << 30))) {
2120ac341f1SConrad Meyer         return NULL; /* LCOV_EXCL_LINE */
2130ac341f1SConrad Meyer     }
2140ac341f1SConrad Meyer     dst    = buf;
2150ac341f1SConrad Meyer     *dst++ = '$';
2160ac341f1SConrad Meyer     *dst++ = '7';
2170ac341f1SConrad Meyer     *dst++ = '$';
2180ac341f1SConrad Meyer 
2190ac341f1SConrad Meyer     *dst++ = itoa64[N_log2];
2200ac341f1SConrad Meyer 
2210ac341f1SConrad Meyer     dst = encode64_uint32(dst, buflen - (dst - buf), r, 30);
2220ac341f1SConrad Meyer     if (!dst) {
2230ac341f1SConrad Meyer         return NULL; /* Can't happen LCOV_EXCL_LINE */
2240ac341f1SConrad Meyer     }
2250ac341f1SConrad Meyer     dst = encode64_uint32(dst, buflen - (dst - buf), p, 30);
2260ac341f1SConrad Meyer     if (!dst) {
2270ac341f1SConrad Meyer         return NULL; /* Can't happen LCOV_EXCL_LINE */
2280ac341f1SConrad Meyer     }
2290ac341f1SConrad Meyer     dst = encode64(dst, buflen - (dst - buf), src, srclen);
2300ac341f1SConrad Meyer     if (!dst || dst >= buf + buflen) {
2310ac341f1SConrad Meyer         return NULL; /* Can't happen LCOV_EXCL_LINE */
2320ac341f1SConrad Meyer     }
2330ac341f1SConrad Meyer     *dst = 0; /* NUL termination */
2340ac341f1SConrad Meyer 
2350ac341f1SConrad Meyer     return buf;
2360ac341f1SConrad Meyer }
2370ac341f1SConrad Meyer 
2380ac341f1SConrad Meyer int
crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t * passwd,size_t passwdlen,const uint8_t * salt,size_t saltlen,uint64_t N,uint32_t r,uint32_t p,uint8_t * buf,size_t buflen)2390ac341f1SConrad Meyer crypto_pwhash_scryptsalsa208sha256_ll(const uint8_t *passwd, size_t passwdlen,
2400ac341f1SConrad Meyer                                       const uint8_t *salt, size_t saltlen,
2410ac341f1SConrad Meyer                                       uint64_t N, uint32_t r, uint32_t p,
2420ac341f1SConrad Meyer                                       uint8_t *buf, size_t buflen)
2430ac341f1SConrad Meyer {
2440ac341f1SConrad Meyer     escrypt_kdf_t   escrypt_kdf;
2450ac341f1SConrad Meyer     escrypt_local_t local;
2460ac341f1SConrad Meyer     int             retval;
2470ac341f1SConrad Meyer 
2480ac341f1SConrad Meyer     if (escrypt_init_local(&local)) {
2490ac341f1SConrad Meyer         return -1; /* LCOV_EXCL_LINE */
2500ac341f1SConrad Meyer     }
2510ac341f1SConrad Meyer #if defined(HAVE_EMMINTRIN_H)
2520ac341f1SConrad Meyer     escrypt_kdf =
2530ac341f1SConrad Meyer         sodium_runtime_has_sse2() ? escrypt_kdf_sse : escrypt_kdf_nosse;
2540ac341f1SConrad Meyer #else
2550ac341f1SConrad Meyer     escrypt_kdf = escrypt_kdf_nosse;
2560ac341f1SConrad Meyer #endif
2570ac341f1SConrad Meyer     retval = escrypt_kdf(&local, passwd, passwdlen, salt, saltlen, N, r, p, buf,
2580ac341f1SConrad Meyer                          buflen);
2590ac341f1SConrad Meyer     if (escrypt_free_local(&local)) {
2600ac341f1SConrad Meyer         return -1; /* LCOV_EXCL_LINE */
2610ac341f1SConrad Meyer     }
2620ac341f1SConrad Meyer     return retval;
2630ac341f1SConrad Meyer }
264