Coverage Report

Created: 2025-06-13 06:43

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