1 /* Copyright (C) 2018 vt@altlinux.org
2 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted.
5 *
6 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
7 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
8 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
9 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
10 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
11 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
12 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
13 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
14 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
15 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
16 * SUCH DAMAGE.
17 */
18
19 #include "crypt-port.h"
20 #include "alg-yescrypt.h"
21
22 #include <errno.h>
23
24 #if INCLUDE_yescrypt || INCLUDE_scrypt
25
26 /* For use in scratch space by crypt_yescrypt_rn(). */
27 typedef struct
28 {
29 yescrypt_local_t local;
30 uint8_t outbuf[CRYPT_OUTPUT_SIZE];
31 uint8_t *retval;
32 } crypt_yescrypt_internal_t;
33
34 static_assert (sizeof (crypt_yescrypt_internal_t) <= ALG_SPECIFIC_SIZE,
35 "ALG_SPECIFIC_SIZE is too small for YESCRYPT.");
36
37 void
38 crypt_yescrypt_rn (const char *phrase, size_t phr_size,
39 const char *setting, size_t set_size,
40 uint8_t *output, size_t o_size,
41 void *scratch, size_t s_size)
42 {
43 #if !INCLUDE_scrypt
44
45 /* If scrypt is disabled fail when called with its prefix. */
46 if (!strncmp (setting, "$7$", 3))
47 {
48 errno = EINVAL;
49 return;
50 }
51
52 #endif /* !INCLUDE_scrypt */
53
54 #if !INCLUDE_yescrypt
55
56 /* If yescrypt is disabled fail when called with its prefix. */
57 if (!strncmp (setting, "$y$", 3))
58 {
59 errno = EINVAL;
60 return;
61 }
62
63 #endif /* !INCLUDE_yescrypt */
64
65 if (o_size < set_size + 1 + 43 + 1 ||
66 CRYPT_OUTPUT_SIZE < set_size + 1 + 43 + 1 ||
67 s_size < sizeof (crypt_yescrypt_internal_t))
68 {
69 errno = ERANGE;
70 return;
71 }
72
73 crypt_yescrypt_internal_t *intbuf = scratch;
74
75 if (yescrypt_init_local (&intbuf->local))
76 return;
77
78 intbuf->retval = yescrypt_r (NULL, &intbuf->local,
79 (const uint8_t *)phrase, phr_size,
80 (const uint8_t *)setting, NULL,
81 intbuf->outbuf, o_size);
82
83 if (!intbuf->retval)
84 errno = EINVAL;
85
86 if (yescrypt_free_local (&intbuf->local) || !intbuf->retval)
87 return;
88
89 strcpy_or_abort (output, o_size, intbuf->outbuf);
90 return;
91 }
92
93 #endif /* INCLUDE_yescrypt || INCLUDE_scrypt */
94
95 #if INCLUDE_gost_yescrypt || INCLUDE_yescrypt
96
97 /*
98 * As OUTPUT is initialized with a failure token before gensalt_yescrypt_rn
99 * is called, in case of an error we could just set an appropriate errno
100 * and return.
101 * Since O_SIZE is guaranteed to be greater than 2, we may fill OUTPUT
102 * with a short failure token when need.
103 */
104 void
105 gensalt_yescrypt_rn (unsigned long count,
106 const uint8_t *rbytes, size_t nrbytes,
107 uint8_t *output, size_t o_size)
108 {
109 /* Up to 512 bits (64 bytes) of entropy for computing the salt portion
110 of the MCF-setting are supported. */
111 nrbytes = (nrbytes > 64 ? 64 : nrbytes);
112
113 if (o_size < 3 + 8 * 6 + 1 + BASE64_LEN (nrbytes) + 1 ||
114 CRYPT_GENSALT_OUTPUT_SIZE < 3 + 8 * 6 + 1 + BASE64_LEN (nrbytes) + 1)
115 {
116 errno = ERANGE;
117 return;
118 }
119
120 if (count > 11 || nrbytes < 16)
121 {
122 errno = EINVAL;
123 return;
124 }
125
126 /* Temporary buffer for operation. The buffer is guaranteed to be
127 large enough to hold the maximum size of the generated salt. */
128 uint8_t outbuf[CRYPT_GENSALT_OUTPUT_SIZE];
129
130 yescrypt_params_t params =
131 {
132 .flags = YESCRYPT_DEFAULTS,
133 .p = 1,
134 };
135
136 /* Valid cost parameters are from 1 to 11. The default is 5.
137 These are used to set yescrypt's 'N' and 'r' parameters as
138 follows:
139 N (block count) is specified in units of r (block size,
140 adjustable in steps of 128 bytes).
141
142 128 bytes * r = size of each memory block
143
144 128 bytes * r * N = total amount of memory used for hashing
145 in N blocks of r * 128 bytes.
146
147 The author of yescrypt recommends in the documentation to use
148 r=8 (a block size of 1 KiB) for total sizes of 2 MiB and less,
149 and r=32 (a block size of 4KiB) above that.
150 This has to do with the typical per-core last-level cache sizes
151 of current CPUs. */
152
153 if (count == 0)
154 count = 5;
155
156 if (count < 3)
157 {
158 params.r = 8; // N in 1KiB
159 params.N = 1ULL << (count + 9); // 1 -> 1024, 2 -> 2048
160 }
161 else
162 {
163 params.r = 32; // N in 4KiB
164 params.N = 1ULL << (count + 7); // 3 -> 1024, 4 -> 2048, ... 11 -> 262144
165 }
166
167 if (!yescrypt_encode_params_r (¶ms, rbytes, nrbytes, outbuf, o_size))
168 {
169 errno = ERANGE;
170 return;
171 }
172
173 strcpy_or_abort (output, o_size, outbuf);
174 return;
175 }
176
177 #endif /* INCLUDE_gost_yescrypt || INCLUDE_yescrypt */