xref: /dflybsd-src/lib/libcrypt/crypt-sha256.c (revision e0369600668aca82fea4c3901659ea23bc610fc0)
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