Coverage Report

Created: 2026-07-25 06:39

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