16737f3b9SNolan Lum /*
2d8ee3b5dSSamuel J. Greear * SHA256-based Unix crypt implementation.
3d8ee3b5dSSamuel J. Greear * Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>.
46737f3b9SNolan Lum */
5d8ee3b5dSSamuel J. Greear #include <errno.h>
6d8ee3b5dSSamuel J. Greear #include <limits.h>
7d8ee3b5dSSamuel J. Greear #include <stdint.h>
8d8ee3b5dSSamuel J. Greear #include <stdbool.h>
9d8ee3b5dSSamuel J. Greear #include <stdio.h>
10d8ee3b5dSSamuel J. Greear #include <stdlib.h>
116737f3b9SNolan Lum #include <string.h>
12d8ee3b5dSSamuel J. Greear #include <sys/endian.h>
13d8ee3b5dSSamuel J. Greear #include <sys/param.h>
14d8ee3b5dSSamuel J. Greear #include <sys/types.h>
156737f3b9SNolan Lum
16*e0369600Szrj #include "crypt.h"
170fe46dc6SMatthew Dillon #include "local.h"
186737f3b9SNolan Lum
194c7c7880SSascha Wildner #if _BYTE_ORDER == _LITTLE_ENDIAN
20d8ee3b5dSSamuel J. Greear # define SWAP(n) \
21d8ee3b5dSSamuel J. Greear (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
22d8ee3b5dSSamuel J. Greear #else
23d8ee3b5dSSamuel J. Greear # define SWAP(n) (n)
24d8ee3b5dSSamuel J. Greear #endif
256737f3b9SNolan Lum
266737f3b9SNolan Lum
27d8ee3b5dSSamuel J. Greear /* This array contains the bytes used to pad the buffer to the next
28d8ee3b5dSSamuel J. Greear 64-byte boundary. (FIPS 180-2:5.1.1) */
29d8ee3b5dSSamuel J. Greear static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ... */ };
306737f3b9SNolan Lum
316737f3b9SNolan Lum
32d8ee3b5dSSamuel J. Greear /* Constants for SHA256 from FIPS 180-2:4.2.2. */
33d8ee3b5dSSamuel J. Greear static const uint32_t K[64] =
34d8ee3b5dSSamuel J. Greear {
35d8ee3b5dSSamuel J. Greear 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
36d8ee3b5dSSamuel J. Greear 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
37d8ee3b5dSSamuel J. Greear 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
38d8ee3b5dSSamuel J. Greear 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
39d8ee3b5dSSamuel J. Greear 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
40d8ee3b5dSSamuel J. Greear 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
41d8ee3b5dSSamuel J. Greear 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
42d8ee3b5dSSamuel J. Greear 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
43d8ee3b5dSSamuel J. Greear 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
44d8ee3b5dSSamuel J. Greear 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
45d8ee3b5dSSamuel J. Greear 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
46d8ee3b5dSSamuel J. Greear 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
47d8ee3b5dSSamuel J. Greear 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
48d8ee3b5dSSamuel J. Greear 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
49d8ee3b5dSSamuel J. Greear 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
50d8ee3b5dSSamuel J. Greear 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
51d8ee3b5dSSamuel J. Greear };
526737f3b9SNolan Lum
536737f3b9SNolan Lum
54d8ee3b5dSSamuel J. Greear /* Process LEN bytes of BUFFER, accumulating context into CTX.
55d8ee3b5dSSamuel J. Greear It is assumed that LEN % 64 == 0. */
560fe46dc6SMatthew Dillon void
__crypt__sha256_process_block(const void * buffer,size_t len,struct sha256_ctx * ctx)570fe46dc6SMatthew Dillon __crypt__sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx)
58d8ee3b5dSSamuel J. Greear {
59d8ee3b5dSSamuel J. Greear const uint32_t *words = buffer;
60d8ee3b5dSSamuel J. Greear size_t nwords = len / sizeof (uint32_t);
61d8ee3b5dSSamuel J. Greear uint32_t a = ctx->H[0];
62d8ee3b5dSSamuel J. Greear uint32_t b = ctx->H[1];
63d8ee3b5dSSamuel J. Greear uint32_t c = ctx->H[2];
64d8ee3b5dSSamuel J. Greear uint32_t d = ctx->H[3];
65d8ee3b5dSSamuel J. Greear uint32_t e = ctx->H[4];
66d8ee3b5dSSamuel J. Greear uint32_t f = ctx->H[5];
67d8ee3b5dSSamuel J. Greear uint32_t g = ctx->H[6];
68d8ee3b5dSSamuel J. Greear uint32_t h = ctx->H[7];
696737f3b9SNolan Lum
70d8ee3b5dSSamuel J. Greear /* First increment the byte count. FIPS 180-2 specifies the possible
71d8ee3b5dSSamuel J. Greear length of the file up to 2^64 bits. Here we only compute the
72d8ee3b5dSSamuel J. Greear number of bytes. Do a double word increment. */
73d8ee3b5dSSamuel J. Greear ctx->total[0] += len;
74d8ee3b5dSSamuel J. Greear if (ctx->total[0] < len)
75d8ee3b5dSSamuel J. Greear ++ctx->total[1];
766737f3b9SNolan Lum
77d8ee3b5dSSamuel J. Greear /* Process all bytes in the buffer with 64 bytes in each round of
78d8ee3b5dSSamuel J. Greear the loop. */
79d8ee3b5dSSamuel J. Greear while (nwords > 0)
80d8ee3b5dSSamuel J. Greear {
81d8ee3b5dSSamuel J. Greear uint32_t W[64];
82d8ee3b5dSSamuel J. Greear uint32_t a_save = a;
83d8ee3b5dSSamuel J. Greear uint32_t b_save = b;
84d8ee3b5dSSamuel J. Greear uint32_t c_save = c;
85d8ee3b5dSSamuel J. Greear uint32_t d_save = d;
86d8ee3b5dSSamuel J. Greear uint32_t e_save = e;
87d8ee3b5dSSamuel J. Greear uint32_t f_save = f;
88d8ee3b5dSSamuel J. Greear uint32_t g_save = g;
89d8ee3b5dSSamuel J. Greear uint32_t h_save = h;
906737f3b9SNolan Lum
91d8ee3b5dSSamuel J. Greear /* Operators defined in FIPS 180-2:4.1.2. */
92d8ee3b5dSSamuel J. Greear #define Ch(x, y, z) ((x & y) ^ (~x & z))
93d8ee3b5dSSamuel J. Greear #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
94d8ee3b5dSSamuel J. Greear #define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22))
95d8ee3b5dSSamuel J. Greear #define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25))
96d8ee3b5dSSamuel J. Greear #define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3))
97d8ee3b5dSSamuel J. Greear #define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10))
986737f3b9SNolan Lum
99d8ee3b5dSSamuel J. Greear /* It is unfortunate that C does not provide an operator for
100d8ee3b5dSSamuel J. Greear cyclic rotation. Hope the C compiler is smart enough. */
101d8ee3b5dSSamuel J. Greear #define CYCLIC(w, s) ((w >> s) | (w << (32 - s)))
102d8ee3b5dSSamuel J. Greear
103d8ee3b5dSSamuel J. Greear /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2. */
104d8ee3b5dSSamuel J. Greear for (unsigned int t = 0; t < 16; ++t)
105d8ee3b5dSSamuel J. Greear {
106d8ee3b5dSSamuel J. Greear W[t] = SWAP (*words);
107d8ee3b5dSSamuel J. Greear ++words;
1086737f3b9SNolan Lum }
109d8ee3b5dSSamuel J. Greear for (unsigned int t = 16; t < 64; ++t)
110d8ee3b5dSSamuel J. Greear W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
111d8ee3b5dSSamuel J. Greear
112d8ee3b5dSSamuel J. Greear /* The actual computation according to FIPS 180-2:6.2.2 step 3. */
113d8ee3b5dSSamuel J. Greear for (unsigned int t = 0; t < 64; ++t)
114d8ee3b5dSSamuel J. Greear {
115d8ee3b5dSSamuel J. Greear uint32_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
116d8ee3b5dSSamuel J. Greear uint32_t T2 = S0 (a) + Maj (a, b, c);
117d8ee3b5dSSamuel J. Greear h = g;
118d8ee3b5dSSamuel J. Greear g = f;
119d8ee3b5dSSamuel J. Greear f = e;
120d8ee3b5dSSamuel J. Greear e = d + T1;
121d8ee3b5dSSamuel J. Greear d = c;
122d8ee3b5dSSamuel J. Greear c = b;
123d8ee3b5dSSamuel J. Greear b = a;
124d8ee3b5dSSamuel J. Greear a = T1 + T2;
125d8ee3b5dSSamuel J. Greear }
126d8ee3b5dSSamuel J. Greear
127d8ee3b5dSSamuel J. Greear /* Add the starting values of the context according to FIPS 180-2:6.2.2
128d8ee3b5dSSamuel J. Greear step 4. */
129d8ee3b5dSSamuel J. Greear a += a_save;
130d8ee3b5dSSamuel J. Greear b += b_save;
131d8ee3b5dSSamuel J. Greear c += c_save;
132d8ee3b5dSSamuel J. Greear d += d_save;
133d8ee3b5dSSamuel J. Greear e += e_save;
134d8ee3b5dSSamuel J. Greear f += f_save;
135d8ee3b5dSSamuel J. Greear g += g_save;
136d8ee3b5dSSamuel J. Greear h += h_save;
137d8ee3b5dSSamuel J. Greear
138d8ee3b5dSSamuel J. Greear /* Prepare for the next round. */
139d8ee3b5dSSamuel J. Greear nwords -= 16;
140d8ee3b5dSSamuel J. Greear }
141d8ee3b5dSSamuel J. Greear
142d8ee3b5dSSamuel J. Greear /* Put checksum in context given as argument. */
143d8ee3b5dSSamuel J. Greear ctx->H[0] = a;
144d8ee3b5dSSamuel J. Greear ctx->H[1] = b;
145d8ee3b5dSSamuel J. Greear ctx->H[2] = c;
146d8ee3b5dSSamuel J. Greear ctx->H[3] = d;
147d8ee3b5dSSamuel J. Greear ctx->H[4] = e;
148d8ee3b5dSSamuel J. Greear ctx->H[5] = f;
149d8ee3b5dSSamuel J. Greear ctx->H[6] = g;
150d8ee3b5dSSamuel J. Greear ctx->H[7] = h;
151d8ee3b5dSSamuel J. Greear }
152d8ee3b5dSSamuel J. Greear
153d8ee3b5dSSamuel J. Greear
154d8ee3b5dSSamuel J. Greear /* Initialize structure containing state of computation.
155d8ee3b5dSSamuel J. Greear (FIPS 180-2:5.3.2) */
1560fe46dc6SMatthew Dillon void
__crypt__sha256_init_ctx(struct sha256_ctx * ctx)1570fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (struct sha256_ctx *ctx)
158d8ee3b5dSSamuel J. Greear {
159d8ee3b5dSSamuel J. Greear ctx->H[0] = 0x6a09e667;
160d8ee3b5dSSamuel J. Greear ctx->H[1] = 0xbb67ae85;
161d8ee3b5dSSamuel J. Greear ctx->H[2] = 0x3c6ef372;
162d8ee3b5dSSamuel J. Greear ctx->H[3] = 0xa54ff53a;
163d8ee3b5dSSamuel J. Greear ctx->H[4] = 0x510e527f;
164d8ee3b5dSSamuel J. Greear ctx->H[5] = 0x9b05688c;
165d8ee3b5dSSamuel J. Greear ctx->H[6] = 0x1f83d9ab;
166d8ee3b5dSSamuel J. Greear ctx->H[7] = 0x5be0cd19;
167d8ee3b5dSSamuel J. Greear
168d8ee3b5dSSamuel J. Greear ctx->total[0] = ctx->total[1] = 0;
169d8ee3b5dSSamuel J. Greear ctx->buflen = 0;
170d8ee3b5dSSamuel J. Greear }
171d8ee3b5dSSamuel J. Greear
172d8ee3b5dSSamuel J. Greear
173d8ee3b5dSSamuel J. Greear /* Process the remaining bytes in the internal buffer and the usual
174d8ee3b5dSSamuel J. Greear prolog according to the standard and write the result to RESBUF.
175d8ee3b5dSSamuel J. Greear
176d8ee3b5dSSamuel J. Greear IMPORTANT: On some systems it is required that RESBUF is correctly
177d8ee3b5dSSamuel J. Greear aligned for a 32 bits value. */
1780fe46dc6SMatthew Dillon void *
__crypt__sha256_finish_ctx(struct sha256_ctx * ctx,void * resbuf)1790fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
180d8ee3b5dSSamuel J. Greear {
181d8ee3b5dSSamuel J. Greear /* Take yet unprocessed bytes into account. */
182d8ee3b5dSSamuel J. Greear uint32_t bytes = ctx->buflen;
183d8ee3b5dSSamuel J. Greear size_t pad;
184d8ee3b5dSSamuel J. Greear
185d8ee3b5dSSamuel J. Greear /* Now count remaining bytes. */
186d8ee3b5dSSamuel J. Greear ctx->total[0] += bytes;
187d8ee3b5dSSamuel J. Greear if (ctx->total[0] < bytes)
188d8ee3b5dSSamuel J. Greear ++ctx->total[1];
189d8ee3b5dSSamuel J. Greear
190d8ee3b5dSSamuel J. Greear pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
191d8ee3b5dSSamuel J. Greear memcpy (&ctx->buffer[bytes], fillbuf, pad);
192d8ee3b5dSSamuel J. Greear
193d8ee3b5dSSamuel J. Greear /* Put the 64-bit file length in *bits* at the end of the buffer. */
194d8ee3b5dSSamuel J. Greear *(uint32_t *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3);
195d8ee3b5dSSamuel J. Greear *(uint32_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) |
196d8ee3b5dSSamuel J. Greear (ctx->total[0] >> 29));
197d8ee3b5dSSamuel J. Greear
198d8ee3b5dSSamuel J. Greear /* Process last bytes. */
1990fe46dc6SMatthew Dillon __crypt__sha256_process_block (ctx->buffer, bytes + pad + 8, ctx);
200d8ee3b5dSSamuel J. Greear
201d8ee3b5dSSamuel J. Greear /* Put result from CTX in first 32 bytes following RESBUF. */
202d8ee3b5dSSamuel J. Greear for (unsigned int i = 0; i < 8; ++i)
203d8ee3b5dSSamuel J. Greear ((uint32_t *) resbuf)[i] = SWAP (ctx->H[i]);
204d8ee3b5dSSamuel J. Greear
205d8ee3b5dSSamuel J. Greear return resbuf;
206d8ee3b5dSSamuel J. Greear }
207d8ee3b5dSSamuel J. Greear
2080fe46dc6SMatthew Dillon void
__crypt__sha256_process_bytes(const void * buffer,size_t len,struct sha256_ctx * ctx)2090fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
210d8ee3b5dSSamuel J. Greear {
211d8ee3b5dSSamuel J. Greear /* When we already have some bits in our internal buffer concatenate
212d8ee3b5dSSamuel J. Greear both inputs first. */
213d8ee3b5dSSamuel J. Greear if (ctx->buflen != 0)
214d8ee3b5dSSamuel J. Greear {
215d8ee3b5dSSamuel J. Greear size_t left_over = ctx->buflen;
216d8ee3b5dSSamuel J. Greear size_t add = 128 - left_over > len ? len : 128 - left_over;
217d8ee3b5dSSamuel J. Greear
218d8ee3b5dSSamuel J. Greear memcpy (&ctx->buffer[left_over], buffer, add);
219d8ee3b5dSSamuel J. Greear ctx->buflen += add;
220d8ee3b5dSSamuel J. Greear
221d8ee3b5dSSamuel J. Greear if (ctx->buflen > 64)
222d8ee3b5dSSamuel J. Greear {
2230fe46dc6SMatthew Dillon __crypt__sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
224d8ee3b5dSSamuel J. Greear
225d8ee3b5dSSamuel J. Greear ctx->buflen &= 63;
226d8ee3b5dSSamuel J. Greear /* The regions in the following copy operation cannot overlap. */
227d8ee3b5dSSamuel J. Greear memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
228d8ee3b5dSSamuel J. Greear ctx->buflen);
229d8ee3b5dSSamuel J. Greear }
230d8ee3b5dSSamuel J. Greear
231d8ee3b5dSSamuel J. Greear buffer = (const char *) buffer + add;
232d8ee3b5dSSamuel J. Greear len -= add;
233d8ee3b5dSSamuel J. Greear }
234d8ee3b5dSSamuel J. Greear
235d8ee3b5dSSamuel J. Greear /* Process available complete blocks. */
236d8ee3b5dSSamuel J. Greear if (len >= 64)
237d8ee3b5dSSamuel J. Greear {
238d8ee3b5dSSamuel J. Greear /* To check alignment gcc has an appropriate operator. Other
239d8ee3b5dSSamuel J. Greear compilers don't. */
240d8ee3b5dSSamuel J. Greear #if __GNUC__ >= 2
241d8ee3b5dSSamuel J. Greear # define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0)
242d8ee3b5dSSamuel J. Greear #else
243d8ee3b5dSSamuel J. Greear # define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0)
244d8ee3b5dSSamuel J. Greear #endif
245d8ee3b5dSSamuel J. Greear if (UNALIGNED_P (buffer))
246d8ee3b5dSSamuel J. Greear while (len > 64)
247d8ee3b5dSSamuel J. Greear {
2480fe46dc6SMatthew Dillon __crypt__sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
249d8ee3b5dSSamuel J. Greear buffer = (const char *) buffer + 64;
250d8ee3b5dSSamuel J. Greear len -= 64;
251d8ee3b5dSSamuel J. Greear }
252d8ee3b5dSSamuel J. Greear else
253d8ee3b5dSSamuel J. Greear {
2540fe46dc6SMatthew Dillon __crypt__sha256_process_block (buffer, len & ~63, ctx);
255d8ee3b5dSSamuel J. Greear buffer = (const char *) buffer + (len & ~63);
256d8ee3b5dSSamuel J. Greear len &= 63;
257d8ee3b5dSSamuel J. Greear }
258d8ee3b5dSSamuel J. Greear }
259d8ee3b5dSSamuel J. Greear
260d8ee3b5dSSamuel J. Greear /* Move remaining bytes into internal buffer. */
261d8ee3b5dSSamuel J. Greear if (len > 0)
262d8ee3b5dSSamuel J. Greear {
263d8ee3b5dSSamuel J. Greear size_t left_over = ctx->buflen;
264d8ee3b5dSSamuel J. Greear
265d8ee3b5dSSamuel J. Greear memcpy (&ctx->buffer[left_over], buffer, len);
266d8ee3b5dSSamuel J. Greear left_over += len;
267d8ee3b5dSSamuel J. Greear if (left_over >= 64)
268d8ee3b5dSSamuel J. Greear {
2690fe46dc6SMatthew Dillon __crypt__sha256_process_block (ctx->buffer, 64, ctx);
270d8ee3b5dSSamuel J. Greear left_over -= 64;
271d8ee3b5dSSamuel J. Greear memcpy (ctx->buffer, &ctx->buffer[64], left_over);
272d8ee3b5dSSamuel J. Greear }
273d8ee3b5dSSamuel J. Greear ctx->buflen = left_over;
274d8ee3b5dSSamuel J. Greear }
275d8ee3b5dSSamuel J. Greear }
276d8ee3b5dSSamuel J. Greear
277d8ee3b5dSSamuel J. Greear
278d8ee3b5dSSamuel J. Greear /* Define our magic string to mark salt for SHA256 "encryption"
279d8ee3b5dSSamuel J. Greear replacement. */
280d8ee3b5dSSamuel J. Greear static const char sha256_salt_prefix[] = "$5$";
281d8ee3b5dSSamuel J. Greear
282d8ee3b5dSSamuel J. Greear /* Prefix for optional rounds specification. */
283d8ee3b5dSSamuel J. Greear static const char sha256_rounds_prefix[] = "rounds=";
284d8ee3b5dSSamuel J. Greear
285d8ee3b5dSSamuel J. Greear /* Maximum salt string length. */
286d8ee3b5dSSamuel J. Greear #define SALT_LEN_MAX 16
287d8ee3b5dSSamuel J. Greear /* Default number of rounds if not explicitly specified. */
288d8ee3b5dSSamuel J. Greear #define ROUNDS_DEFAULT 5000
289d8ee3b5dSSamuel J. Greear /* Minimum number of rounds. */
290d8ee3b5dSSamuel J. Greear #define ROUNDS_MIN 1000
291d8ee3b5dSSamuel J. Greear /* Maximum number of rounds. */
292d8ee3b5dSSamuel J. Greear #define ROUNDS_MAX 999999999
293d8ee3b5dSSamuel J. Greear
294d8ee3b5dSSamuel J. Greear /* Table with characters for base64 transformation. */
295d8ee3b5dSSamuel J. Greear static const char b64t[64] =
296d8ee3b5dSSamuel J. Greear "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
297d8ee3b5dSSamuel J. Greear
298d8ee3b5dSSamuel J. Greear
299d8ee3b5dSSamuel J. Greear static char *
crypt_sha256_r(const char * key,const char * salt,char * buffer,int buflen)300d8ee3b5dSSamuel J. Greear crypt_sha256_r (const char *key, const char *salt, char *buffer, int buflen)
301d8ee3b5dSSamuel J. Greear {
302d8ee3b5dSSamuel J. Greear unsigned char alt_result[32]
303d8ee3b5dSSamuel J. Greear __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
304d8ee3b5dSSamuel J. Greear unsigned char temp_result[32]
305d8ee3b5dSSamuel J. Greear __attribute__ ((__aligned__ (__alignof__ (uint32_t))));
306d8ee3b5dSSamuel J. Greear struct sha256_ctx ctx;
307d8ee3b5dSSamuel J. Greear struct sha256_ctx alt_ctx;
308d8ee3b5dSSamuel J. Greear size_t salt_len;
309d8ee3b5dSSamuel J. Greear size_t key_len;
310d8ee3b5dSSamuel J. Greear size_t cnt;
311d8ee3b5dSSamuel J. Greear char *cp;
312d8ee3b5dSSamuel J. Greear char *copied_key = NULL;
313d8ee3b5dSSamuel J. Greear char *copied_salt = NULL;
314d8ee3b5dSSamuel J. Greear char *p_bytes;
315d8ee3b5dSSamuel J. Greear char *s_bytes;
316d8ee3b5dSSamuel J. Greear /* Default number of rounds. */
317d8ee3b5dSSamuel J. Greear size_t rounds = ROUNDS_DEFAULT;
318d8ee3b5dSSamuel J. Greear bool rounds_custom = false;
319d8ee3b5dSSamuel J. Greear
320d8ee3b5dSSamuel J. Greear /* Find beginning of salt string. The prefix should normally always
321d8ee3b5dSSamuel J. Greear be present. Just in case it is not. */
322d8ee3b5dSSamuel J. Greear if (strncmp (sha256_salt_prefix, salt, sizeof (sha256_salt_prefix) - 1) == 0)
323d8ee3b5dSSamuel J. Greear /* Skip salt prefix. */
324d8ee3b5dSSamuel J. Greear salt += sizeof (sha256_salt_prefix) - 1;
325d8ee3b5dSSamuel J. Greear
326d8ee3b5dSSamuel J. Greear if (strncmp (salt, sha256_rounds_prefix, sizeof (sha256_rounds_prefix) - 1)
327d8ee3b5dSSamuel J. Greear == 0)
328d8ee3b5dSSamuel J. Greear {
329d8ee3b5dSSamuel J. Greear const char *num = salt + sizeof (sha256_rounds_prefix) - 1;
330d8ee3b5dSSamuel J. Greear char *endp;
331d8ee3b5dSSamuel J. Greear unsigned long int srounds = strtoul (num, &endp, 10);
332d8ee3b5dSSamuel J. Greear if (*endp == '$')
333d8ee3b5dSSamuel J. Greear {
334d8ee3b5dSSamuel J. Greear salt = endp + 1;
335d8ee3b5dSSamuel J. Greear rounds = MAX (ROUNDS_MIN, MIN (srounds, ROUNDS_MAX));
336d8ee3b5dSSamuel J. Greear rounds_custom = true;
337d8ee3b5dSSamuel J. Greear }
338d8ee3b5dSSamuel J. Greear }
339d8ee3b5dSSamuel J. Greear
340d8ee3b5dSSamuel J. Greear salt_len = MIN (strcspn (salt, "$"), SALT_LEN_MAX);
341d8ee3b5dSSamuel J. Greear key_len = strlen (key);
342d8ee3b5dSSamuel J. Greear
343d8ee3b5dSSamuel J. Greear if ((key - (char *) 0) % __alignof__ (uint32_t) != 0)
344d8ee3b5dSSamuel J. Greear {
345d8ee3b5dSSamuel J. Greear char *tmp = (char *) alloca (key_len + __alignof__ (uint32_t));
346d8ee3b5dSSamuel J. Greear key = copied_key =
347d8ee3b5dSSamuel J. Greear memcpy (tmp + __alignof__ (uint32_t)
348d8ee3b5dSSamuel J. Greear - (tmp - (char *) 0) % __alignof__ (uint32_t),
349d8ee3b5dSSamuel J. Greear key, key_len);
350d8ee3b5dSSamuel J. Greear }
351d8ee3b5dSSamuel J. Greear
352d8ee3b5dSSamuel J. Greear if ((salt - (char *) 0) % __alignof__ (uint32_t) != 0)
353d8ee3b5dSSamuel J. Greear {
354d8ee3b5dSSamuel J. Greear char *tmp = (char *) alloca (salt_len + __alignof__ (uint32_t));
355d8ee3b5dSSamuel J. Greear salt = copied_salt =
356d8ee3b5dSSamuel J. Greear memcpy (tmp + __alignof__ (uint32_t)
357d8ee3b5dSSamuel J. Greear - (tmp - (char *) 0) % __alignof__ (uint32_t),
358d8ee3b5dSSamuel J. Greear salt, salt_len);
359d8ee3b5dSSamuel J. Greear }
360d8ee3b5dSSamuel J. Greear
361d8ee3b5dSSamuel J. Greear /* Prepare for the real work. */
3620fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&ctx);
363d8ee3b5dSSamuel J. Greear
364d8ee3b5dSSamuel J. Greear /* Add the key string. */
3650fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (key, key_len, &ctx);
366d8ee3b5dSSamuel J. Greear
367d8ee3b5dSSamuel J. Greear /* The last part is the salt string. This must be at most 16
368d8ee3b5dSSamuel J. Greear characters and it ends at the first `$' character (for
369d8ee3b5dSSamuel J. Greear compatibility with existing implementations). */
3700fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (salt, salt_len, &ctx);
371d8ee3b5dSSamuel J. Greear
372d8ee3b5dSSamuel J. Greear
373d8ee3b5dSSamuel J. Greear /* Compute alternate SHA256 sum with input KEY, SALT, and KEY. The
374d8ee3b5dSSamuel J. Greear final result will be added to the first context. */
3750fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&alt_ctx);
376d8ee3b5dSSamuel J. Greear
377d8ee3b5dSSamuel J. Greear /* Add key. */
3780fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (key, key_len, &alt_ctx);
379d8ee3b5dSSamuel J. Greear
380d8ee3b5dSSamuel J. Greear /* Add salt. */
3810fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (salt, salt_len, &alt_ctx);
382d8ee3b5dSSamuel J. Greear
383d8ee3b5dSSamuel J. Greear /* Add key again. */
3840fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (key, key_len, &alt_ctx);
385d8ee3b5dSSamuel J. Greear
386d8ee3b5dSSamuel J. Greear /* Now get result of this (32 bytes) and add it to the other
387d8ee3b5dSSamuel J. Greear context. */
3880fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&alt_ctx, alt_result);
389d8ee3b5dSSamuel J. Greear
390d8ee3b5dSSamuel J. Greear /* Add for any character in the key one byte of the alternate sum. */
391d8ee3b5dSSamuel J. Greear for (cnt = key_len; cnt > 32; cnt -= 32)
3920fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (alt_result, 32, &ctx);
3930fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (alt_result, cnt, &ctx);
394d8ee3b5dSSamuel J. Greear
395d8ee3b5dSSamuel J. Greear /* Take the binary representation of the length of the key and for every
396d8ee3b5dSSamuel J. Greear 1 add the alternate sum, for every 0 the key. */
397d8ee3b5dSSamuel J. Greear for (cnt = key_len; cnt > 0; cnt >>= 1)
398d8ee3b5dSSamuel J. Greear if ((cnt & 1) != 0)
3990fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (alt_result, 32, &ctx);
400d8ee3b5dSSamuel J. Greear else
4010fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (key, key_len, &ctx);
402d8ee3b5dSSamuel J. Greear
403d8ee3b5dSSamuel J. Greear /* Create intermediate result. */
4040fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&ctx, alt_result);
405d8ee3b5dSSamuel J. Greear
406d8ee3b5dSSamuel J. Greear /* Start computation of P byte sequence. */
4070fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&alt_ctx);
408d8ee3b5dSSamuel J. Greear
409d8ee3b5dSSamuel J. Greear /* For every character in the password add the entire password. */
410d8ee3b5dSSamuel J. Greear for (cnt = 0; cnt < key_len; ++cnt)
4110fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (key, key_len, &alt_ctx);
412d8ee3b5dSSamuel J. Greear
413d8ee3b5dSSamuel J. Greear /* Finish the digest. */
4140fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&alt_ctx, temp_result);
415d8ee3b5dSSamuel J. Greear
416d8ee3b5dSSamuel J. Greear /* Create byte sequence P. */
417d8ee3b5dSSamuel J. Greear cp = p_bytes = alloca (key_len);
418d8ee3b5dSSamuel J. Greear for (cnt = key_len; cnt >= 32; cnt -= 32)
419d8ee3b5dSSamuel J. Greear cp = mempcpy (cp, temp_result, 32);
420d8ee3b5dSSamuel J. Greear memcpy (cp, temp_result, cnt);
421d8ee3b5dSSamuel J. Greear
422d8ee3b5dSSamuel J. Greear /* Start computation of S byte sequence. */
4230fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&alt_ctx);
424d8ee3b5dSSamuel J. Greear
425d8ee3b5dSSamuel J. Greear /* For every character in the password add the entire password. */
426d8ee3b5dSSamuel J. Greear for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt)
4270fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (salt, salt_len, &alt_ctx);
428d8ee3b5dSSamuel J. Greear
429d8ee3b5dSSamuel J. Greear /* Finish the digest. */
4300fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&alt_ctx, temp_result);
431d8ee3b5dSSamuel J. Greear
432d8ee3b5dSSamuel J. Greear /* Create byte sequence S. */
433d8ee3b5dSSamuel J. Greear cp = s_bytes = alloca (salt_len);
434d8ee3b5dSSamuel J. Greear for (cnt = salt_len; cnt >= 32; cnt -= 32)
435d8ee3b5dSSamuel J. Greear cp = mempcpy (cp, temp_result, 32);
436d8ee3b5dSSamuel J. Greear memcpy (cp, temp_result, cnt);
437d8ee3b5dSSamuel J. Greear
438d8ee3b5dSSamuel J. Greear /* Repeatedly run the collected hash value through SHA256 to burn
439d8ee3b5dSSamuel J. Greear CPU cycles. */
440d8ee3b5dSSamuel J. Greear for (cnt = 0; cnt < rounds; ++cnt)
441d8ee3b5dSSamuel J. Greear {
442d8ee3b5dSSamuel J. Greear /* New context. */
4430fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&ctx);
444d8ee3b5dSSamuel J. Greear
445d8ee3b5dSSamuel J. Greear /* Add key or last result. */
446d8ee3b5dSSamuel J. Greear if ((cnt & 1) != 0)
4470fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (p_bytes, key_len, &ctx);
448d8ee3b5dSSamuel J. Greear else
4490fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (alt_result, 32, &ctx);
450d8ee3b5dSSamuel J. Greear
451d8ee3b5dSSamuel J. Greear /* Add salt for numbers not divisible by 3. */
452d8ee3b5dSSamuel J. Greear if (cnt % 3 != 0)
4530fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (s_bytes, salt_len, &ctx);
454d8ee3b5dSSamuel J. Greear
455d8ee3b5dSSamuel J. Greear /* Add key for numbers not divisible by 7. */
456d8ee3b5dSSamuel J. Greear if (cnt % 7 != 0)
4570fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (p_bytes, key_len, &ctx);
458d8ee3b5dSSamuel J. Greear
459d8ee3b5dSSamuel J. Greear /* Add key or last result. */
460d8ee3b5dSSamuel J. Greear if ((cnt & 1) != 0)
4610fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (alt_result, 32, &ctx);
462d8ee3b5dSSamuel J. Greear else
4630fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (p_bytes, key_len, &ctx);
464d8ee3b5dSSamuel J. Greear
465d8ee3b5dSSamuel J. Greear /* Create intermediate result. */
4660fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&ctx, alt_result);
467d8ee3b5dSSamuel J. Greear }
468d8ee3b5dSSamuel J. Greear
469d8ee3b5dSSamuel J. Greear /* Now we can construct the result string. It consists of three
470d8ee3b5dSSamuel J. Greear parts. */
471d8ee3b5dSSamuel J. Greear cp = stpncpy (buffer, sha256_salt_prefix, MAX (0, buflen));
472d8ee3b5dSSamuel J. Greear buflen -= sizeof (sha256_salt_prefix) - 1;
473d8ee3b5dSSamuel J. Greear
474d8ee3b5dSSamuel J. Greear if (rounds_custom)
475d8ee3b5dSSamuel J. Greear {
476d8ee3b5dSSamuel J. Greear int n = snprintf (cp, MAX (0, buflen), "%s%zu$",
477d8ee3b5dSSamuel J. Greear sha256_rounds_prefix, rounds);
478d8ee3b5dSSamuel J. Greear cp += n;
479d8ee3b5dSSamuel J. Greear buflen -= n;
480d8ee3b5dSSamuel J. Greear }
481d8ee3b5dSSamuel J. Greear
482d8ee3b5dSSamuel J. Greear cp = stpncpy (cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
483d8ee3b5dSSamuel J. Greear buflen -= MIN ((size_t) MAX (0, buflen), salt_len);
484d8ee3b5dSSamuel J. Greear
485d8ee3b5dSSamuel J. Greear if (buflen > 0)
486d8ee3b5dSSamuel J. Greear {
487d8ee3b5dSSamuel J. Greear *cp++ = '$';
488d8ee3b5dSSamuel J. Greear --buflen;
489d8ee3b5dSSamuel J. Greear }
490d8ee3b5dSSamuel J. Greear
491d8ee3b5dSSamuel J. Greear #define b64_from_24bit(B2, B1, B0, N) \
492d8ee3b5dSSamuel J. Greear do { \
493d8ee3b5dSSamuel J. Greear unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0); \
494d8ee3b5dSSamuel J. Greear int n = (N); \
495d8ee3b5dSSamuel J. Greear while (n-- > 0 && buflen > 0) \
496d8ee3b5dSSamuel J. Greear { \
497d8ee3b5dSSamuel J. Greear *cp++ = b64t[w & 0x3f]; \
498d8ee3b5dSSamuel J. Greear --buflen; \
499d8ee3b5dSSamuel J. Greear w >>= 6; \
500d8ee3b5dSSamuel J. Greear } \
501d8ee3b5dSSamuel J. Greear } while (0)
502d8ee3b5dSSamuel J. Greear
503d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[0], alt_result[10], alt_result[20], 4);
504d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[21], alt_result[1], alt_result[11], 4);
505d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[12], alt_result[22], alt_result[2], 4);
506d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[3], alt_result[13], alt_result[23], 4);
507d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[24], alt_result[4], alt_result[14], 4);
508d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[15], alt_result[25], alt_result[5], 4);
509d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[6], alt_result[16], alt_result[26], 4);
510d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[27], alt_result[7], alt_result[17], 4);
511d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[18], alt_result[28], alt_result[8], 4);
512d8ee3b5dSSamuel J. Greear b64_from_24bit (alt_result[9], alt_result[19], alt_result[29], 4);
513d8ee3b5dSSamuel J. Greear b64_from_24bit (0, alt_result[31], alt_result[30], 3);
514d8ee3b5dSSamuel J. Greear if (buflen <= 0)
515d8ee3b5dSSamuel J. Greear {
516d8ee3b5dSSamuel J. Greear errno = ERANGE;
517d8ee3b5dSSamuel J. Greear buffer = NULL;
518d8ee3b5dSSamuel J. Greear }
519d8ee3b5dSSamuel J. Greear else
520d8ee3b5dSSamuel J. Greear *cp = '\0'; /* Terminate the string. */
521d8ee3b5dSSamuel J. Greear
522d8ee3b5dSSamuel J. Greear /* Clear the buffer for the intermediate result so that people
523d8ee3b5dSSamuel J. Greear attaching to processes or reading core dumps cannot get any
524d8ee3b5dSSamuel J. Greear information. We do it in this way to clear correct_words[]
525d8ee3b5dSSamuel J. Greear inside the SHA256 implementation as well. */
5260fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&ctx);
5270fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&ctx, alt_result);
528d8ee3b5dSSamuel J. Greear memset (temp_result, '\0', sizeof (temp_result));
529d8ee3b5dSSamuel J. Greear memset (p_bytes, '\0', key_len);
530d8ee3b5dSSamuel J. Greear memset (s_bytes, '\0', salt_len);
531d8ee3b5dSSamuel J. Greear memset (&ctx, '\0', sizeof (ctx));
532d8ee3b5dSSamuel J. Greear memset (&alt_ctx, '\0', sizeof (alt_ctx));
533d8ee3b5dSSamuel J. Greear if (copied_key != NULL)
534d8ee3b5dSSamuel J. Greear memset (copied_key, '\0', key_len);
535d8ee3b5dSSamuel J. Greear if (copied_salt != NULL)
536d8ee3b5dSSamuel J. Greear memset (copied_salt, '\0', salt_len);
537d8ee3b5dSSamuel J. Greear
538d8ee3b5dSSamuel J. Greear return buffer;
539d8ee3b5dSSamuel J. Greear }
540d8ee3b5dSSamuel J. Greear
541d8ee3b5dSSamuel J. Greear
542d8ee3b5dSSamuel J. Greear /* This entry point is equivalent to the `crypt' function in Unix
543d8ee3b5dSSamuel J. Greear libcs. */
544d8ee3b5dSSamuel J. Greear char *
crypt_sha256(const char * key,const char * salt)545d8ee3b5dSSamuel J. Greear crypt_sha256 (const char *key, const char *salt)
546d8ee3b5dSSamuel J. Greear {
547d8ee3b5dSSamuel J. Greear /* We don't want to have an arbitrary limit in the size of the
548d8ee3b5dSSamuel J. Greear password. We can compute an upper bound for the size of the
549d8ee3b5dSSamuel J. Greear result in advance and so we can prepare the buffer we pass to
550d8ee3b5dSSamuel J. Greear `crypt_sha256_r'. */
551d8ee3b5dSSamuel J. Greear static char *buffer;
552d8ee3b5dSSamuel J. Greear static int buflen;
553d8ee3b5dSSamuel J. Greear int needed = (sizeof (sha256_salt_prefix) - 1
554d8ee3b5dSSamuel J. Greear + sizeof (sha256_rounds_prefix) + 9 + 1
555d8ee3b5dSSamuel J. Greear + strlen (salt) + 1 + 43 + 1);
556d8ee3b5dSSamuel J. Greear
557d8ee3b5dSSamuel J. Greear if (buflen < needed)
558d8ee3b5dSSamuel J. Greear {
559d8ee3b5dSSamuel J. Greear char *new_buffer = (char *) realloc (buffer, needed);
560d8ee3b5dSSamuel J. Greear if (new_buffer == NULL)
561d8ee3b5dSSamuel J. Greear return NULL;
562d8ee3b5dSSamuel J. Greear
563d8ee3b5dSSamuel J. Greear buffer = new_buffer;
564d8ee3b5dSSamuel J. Greear buflen = needed;
565d8ee3b5dSSamuel J. Greear }
566d8ee3b5dSSamuel J. Greear
567d8ee3b5dSSamuel J. Greear return crypt_sha256_r (key, salt, buffer, buflen);
568d8ee3b5dSSamuel J. Greear }
569d8ee3b5dSSamuel J. Greear
570d8ee3b5dSSamuel J. Greear
571d8ee3b5dSSamuel J. Greear #ifdef TEST
572d8ee3b5dSSamuel J. Greear static const struct
573d8ee3b5dSSamuel J. Greear {
574d8ee3b5dSSamuel J. Greear const char *input;
575d8ee3b5dSSamuel J. Greear const char result[32];
576d8ee3b5dSSamuel J. Greear } tests[] =
577d8ee3b5dSSamuel J. Greear {
578d8ee3b5dSSamuel J. Greear /* Test vectors from FIPS 180-2: appendix B.1. */
579d8ee3b5dSSamuel J. Greear { "abc",
580d8ee3b5dSSamuel J. Greear "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
581d8ee3b5dSSamuel J. Greear "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
582d8ee3b5dSSamuel J. Greear /* Test vectors from FIPS 180-2: appendix B.2. */
583d8ee3b5dSSamuel J. Greear { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
584d8ee3b5dSSamuel J. Greear "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
585d8ee3b5dSSamuel J. Greear "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
586d8ee3b5dSSamuel J. Greear /* Test vectors from the NESSIE project. */
587d8ee3b5dSSamuel J. Greear { "",
588d8ee3b5dSSamuel J. Greear "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24"
589d8ee3b5dSSamuel J. Greear "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55" },
590d8ee3b5dSSamuel J. Greear { "a",
591d8ee3b5dSSamuel J. Greear "\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d"
592d8ee3b5dSSamuel J. Greear "\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb" },
593d8ee3b5dSSamuel J. Greear { "message digest",
594d8ee3b5dSSamuel J. Greear "\xf7\x84\x6f\x55\xcf\x23\xe1\x4e\xeb\xea\xb5\xb4\xe1\x55\x0c\xad"
595d8ee3b5dSSamuel J. Greear "\x5b\x50\x9e\x33\x48\xfb\xc4\xef\xa3\xa1\x41\x3d\x39\x3c\xb6\x50" },
596d8ee3b5dSSamuel J. Greear { "abcdefghijklmnopqrstuvwxyz",
597d8ee3b5dSSamuel J. Greear "\x71\xc4\x80\xdf\x93\xd6\xae\x2f\x1e\xfa\xd1\x44\x7c\x66\xc9\x52"
598d8ee3b5dSSamuel J. Greear "\x5e\x31\x62\x18\xcf\x51\xfc\x8d\x9e\xd8\x32\xf2\xda\xf1\x8b\x73" },
599d8ee3b5dSSamuel J. Greear { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
600d8ee3b5dSSamuel J. Greear "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
601d8ee3b5dSSamuel J. Greear "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
602d8ee3b5dSSamuel J. Greear { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
603d8ee3b5dSSamuel J. Greear "\xdb\x4b\xfc\xbd\x4d\xa0\xcd\x85\xa6\x0c\x3c\x37\xd3\xfb\xd8\x80"
604d8ee3b5dSSamuel J. Greear "\x5c\x77\xf1\x5f\xc6\xb1\xfd\xfe\x61\x4e\xe0\xa7\xc8\xfd\xb4\xc0" },
605d8ee3b5dSSamuel J. Greear { "123456789012345678901234567890123456789012345678901234567890"
606d8ee3b5dSSamuel J. Greear "12345678901234567890",
607d8ee3b5dSSamuel J. Greear "\xf3\x71\xbc\x4a\x31\x1f\x2b\x00\x9e\xef\x95\x2d\xd8\x3c\xa8\x0e"
608d8ee3b5dSSamuel J. Greear "\x2b\x60\x02\x6c\x8e\x93\x55\x92\xd0\xf9\xc3\x08\x45\x3c\x81\x3e" }
609d8ee3b5dSSamuel J. Greear };
610e62ef63cSSascha Wildner #define ntests (NELEM(tests))
611d8ee3b5dSSamuel J. Greear
612d8ee3b5dSSamuel J. Greear
613d8ee3b5dSSamuel J. Greear static const struct
614d8ee3b5dSSamuel J. Greear {
615d8ee3b5dSSamuel J. Greear const char *salt;
616d8ee3b5dSSamuel J. Greear const char *input;
617d8ee3b5dSSamuel J. Greear const char *expected;
618d8ee3b5dSSamuel J. Greear } tests2[] =
619d8ee3b5dSSamuel J. Greear {
620d8ee3b5dSSamuel J. Greear { "$5$saltstring", "Hello world!",
621d8ee3b5dSSamuel J. Greear "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5" },
622d8ee3b5dSSamuel J. Greear { "$5$rounds=10000$saltstringsaltstring", "Hello world!",
623d8ee3b5dSSamuel J. Greear "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2."
624d8ee3b5dSSamuel J. Greear "opqey6IcA" },
625d8ee3b5dSSamuel J. Greear { "$5$rounds=5000$toolongsaltstring", "This is just a test",
626d8ee3b5dSSamuel J. Greear "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8"
627d8ee3b5dSSamuel J. Greear "mGRcvxa5" },
628d8ee3b5dSSamuel J. Greear { "$5$rounds=1400$anotherlongsaltstring",
629d8ee3b5dSSamuel J. Greear "a very much longer text to encrypt. This one even stretches over more"
630d8ee3b5dSSamuel J. Greear "than one line.",
631d8ee3b5dSSamuel J. Greear "$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12"
632d8ee3b5dSSamuel J. Greear "oP84Bnq1" },
633d8ee3b5dSSamuel J. Greear { "$5$rounds=77777$short",
634d8ee3b5dSSamuel J. Greear "we have a short salt string but not a short password",
635d8ee3b5dSSamuel J. Greear "$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/" },
636d8ee3b5dSSamuel J. Greear { "$5$rounds=123456$asaltof16chars..", "a short string",
637d8ee3b5dSSamuel J. Greear "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/"
638d8ee3b5dSSamuel J. Greear "cZKmF/wJvD" },
639d8ee3b5dSSamuel J. Greear { "$5$rounds=10$roundstoolow", "the minimum number is still observed",
640d8ee3b5dSSamuel J. Greear "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97"
641d8ee3b5dSSamuel J. Greear "2bIC" },
642d8ee3b5dSSamuel J. Greear };
643e62ef63cSSascha Wildner #define ntests2 (NELEM(tests2))
644d8ee3b5dSSamuel J. Greear
645d8ee3b5dSSamuel J. Greear
646d8ee3b5dSSamuel J. Greear int
main(void)647d8ee3b5dSSamuel J. Greear main (void)
648d8ee3b5dSSamuel J. Greear {
649d8ee3b5dSSamuel J. Greear struct sha256_ctx ctx;
650d8ee3b5dSSamuel J. Greear char sum[32];
651d8ee3b5dSSamuel J. Greear int result = 0;
652d8ee3b5dSSamuel J. Greear int cnt;
653d8ee3b5dSSamuel J. Greear
654d8ee3b5dSSamuel J. Greear for (cnt = 0; cnt < (int) ntests; ++cnt)
655d8ee3b5dSSamuel J. Greear {
6560fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&ctx);
6570fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (tests[cnt].input, strlen (tests[cnt].input), &ctx);
6580fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&ctx, sum);
659d8ee3b5dSSamuel J. Greear if (memcmp (tests[cnt].result, sum, 32) != 0)
660d8ee3b5dSSamuel J. Greear {
661d8ee3b5dSSamuel J. Greear printf ("test %d run %d failed\n", cnt, 1);
662d8ee3b5dSSamuel J. Greear result = 1;
663d8ee3b5dSSamuel J. Greear }
664d8ee3b5dSSamuel J. Greear
6650fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&ctx);
666d8ee3b5dSSamuel J. Greear for (int i = 0; tests[cnt].input[i] != '\0'; ++i)
6670fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (&tests[cnt].input[i], 1, &ctx);
6680fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&ctx, sum);
669d8ee3b5dSSamuel J. Greear if (memcmp (tests[cnt].result, sum, 32) != 0)
670d8ee3b5dSSamuel J. Greear {
671d8ee3b5dSSamuel J. Greear printf ("test %d run %d failed\n", cnt, 2);
672d8ee3b5dSSamuel J. Greear result = 1;
673d8ee3b5dSSamuel J. Greear }
674d8ee3b5dSSamuel J. Greear }
675d8ee3b5dSSamuel J. Greear
676d8ee3b5dSSamuel J. Greear /* Test vector from FIPS 180-2: appendix B.3. */
677d8ee3b5dSSamuel J. Greear char buf[1000];
678d8ee3b5dSSamuel J. Greear memset (buf, 'a', sizeof (buf));
6790fe46dc6SMatthew Dillon __crypt__sha256_init_ctx (&ctx);
680d8ee3b5dSSamuel J. Greear for (int i = 0; i < 1000; ++i)
6810fe46dc6SMatthew Dillon __crypt__sha256_process_bytes (buf, sizeof (buf), &ctx);
6820fe46dc6SMatthew Dillon __crypt__sha256_finish_ctx (&ctx, sum);
683d8ee3b5dSSamuel J. Greear static const char expected[32] =
684d8ee3b5dSSamuel J. Greear "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
685d8ee3b5dSSamuel J. Greear "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0";
686d8ee3b5dSSamuel J. Greear if (memcmp (expected, sum, 32) != 0)
687d8ee3b5dSSamuel J. Greear {
688d8ee3b5dSSamuel J. Greear printf ("test %d failed\n", cnt);
689d8ee3b5dSSamuel J. Greear result = 1;
690d8ee3b5dSSamuel J. Greear }
691d8ee3b5dSSamuel J. Greear
692d8ee3b5dSSamuel J. Greear for (cnt = 0; cnt < ntests2; ++cnt)
693d8ee3b5dSSamuel J. Greear {
694d8ee3b5dSSamuel J. Greear char *cp = crypt_sha256 (tests2[cnt].input, tests2[cnt].salt);
695d8ee3b5dSSamuel J. Greear
696d8ee3b5dSSamuel J. Greear if (strcmp (cp, tests2[cnt].expected) != 0)
697d8ee3b5dSSamuel J. Greear {
698d8ee3b5dSSamuel J. Greear printf ("test %d: expected \"%s\", got \"%s\"\n",
699d8ee3b5dSSamuel J. Greear cnt, tests2[cnt].expected, cp);
700d8ee3b5dSSamuel J. Greear result = 1;
701d8ee3b5dSSamuel J. Greear }
702d8ee3b5dSSamuel J. Greear }
703d8ee3b5dSSamuel J. Greear
704d8ee3b5dSSamuel J. Greear if (result == 0)
705d8ee3b5dSSamuel J. Greear puts ("all tests OK");
706d8ee3b5dSSamuel J. Greear
707d8ee3b5dSSamuel J. Greear return result;
708d8ee3b5dSSamuel J. Greear }
709d8ee3b5dSSamuel J. Greear #endif
710d8ee3b5dSSamuel J. Greear
711