Back to index

php5  5.3.10
crypt_sha256.c
Go to the documentation of this file.
00001 /* SHA256-based Unix crypt implementation.
00002    Released into the Public Domain by Ulrich Drepper <drepper@redhat.com>.  */
00003 /* Windows VC++ port by Pierre Joye <pierre@php.net> */
00004 
00005 #include "php.h"
00006 #include "php_main.h"
00007 
00008 #include <errno.h>
00009 #include <limits.h>
00010 
00011 #ifdef PHP_WIN32
00012 # include "win32/php_stdint.h"
00013 # define __alignof__ __alignof
00014 # define alloca _alloca
00015 #else
00016 # if HAVE_INTTYPES_H
00017 #  include <inttypes.h>
00018 # elif HAVE_STDINT_H
00019 #  include <stdint.h>
00020 # endif
00021 # ifndef HAVE_ALIGNOF
00022 #  include <stddef.h>
00023 #  define __alignof__(type) offsetof (struct { char c; type member;}, member)
00024 # endif
00025 # if HAVE_ATTRIBUTE_ALIGNED
00026 #  define ALIGNED(size) __attribute__ ((__aligned__ (size)))
00027 # else
00028 #  define ALIGNED(size)
00029 # endif
00030 #endif
00031 
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 
00035 #ifdef PHP_WIN32
00036 # include <string.h>
00037 #else
00038 # include <sys/param.h>
00039 # include <sys/types.h>
00040 # if HAVE_STRING_H
00041 #  include <string.h>
00042 # else
00043 #  include <strings.h>
00044 # endif
00045 #endif
00046 
00047 char * __php_stpncpy(char *dst, const char *src, size_t len)
00048 {
00049        size_t n = strlen(src);
00050        if (n > len) {
00051               n = len;
00052        }
00053        return strncpy(dst, src, len) + n;
00054 }
00055 
00056 void * __php_mempcpy(void * dst, const void * src, size_t len)
00057 {
00058        return (((char *)memcpy(dst, src, len)) + len);
00059 }
00060 
00061 #ifndef MIN
00062 # define MIN(a, b) (((a) < (b)) ? (a) : (b))
00063 #endif
00064 #ifndef MAX
00065 # define MAX(a, b) (((a) > (b)) ? (a) : (b))
00066 #endif
00067 
00068 /* Structure to save state of computation between the single steps.  */
00069 struct sha256_ctx {
00070        uint32_t H[8];
00071 
00072        uint32_t total[2];
00073        uint32_t buflen;
00074        char buffer[128]; /* NB: always correctly aligned for uint32_t.  */
00075 };
00076 
00077 #if PHP_WIN32 || (!defined(WORDS_BIGENDIAN))
00078 # define SWAP(n) \
00079     (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
00080 #else
00081 # define SWAP(n) (n)
00082 #endif
00083 
00084 /* This array contains the bytes used to pad the buffer to the next
00085    64-byte boundary.  (FIPS 180-2:5.1.1)  */
00086 static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
00087 
00088 
00089 /* Constants for SHA256 from FIPS 180-2:4.2.2.  */
00090 static const uint32_t K[64] = {
00091        0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
00092        0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
00093        0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
00094        0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
00095        0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
00096        0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
00097        0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
00098        0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
00099        0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
00100        0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
00101        0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
00102        0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
00103        0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
00104        0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
00105        0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
00106        0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
00107 };
00108 
00109 
00110 /* Process LEN bytes of BUFFER, accumulating context into CTX.
00111    It is assumed that LEN % 64 == 0.  */
00112 static void sha256_process_block (const void *buffer, size_t len, struct sha256_ctx *ctx) {
00113        const uint32_t *words = buffer;
00114        size_t nwords = len / sizeof (uint32_t);
00115        unsigned int t;
00116 
00117        uint32_t a = ctx->H[0];
00118        uint32_t b = ctx->H[1];
00119        uint32_t c = ctx->H[2];
00120        uint32_t d = ctx->H[3];
00121        uint32_t e = ctx->H[4];
00122        uint32_t f = ctx->H[5];
00123        uint32_t g = ctx->H[6];
00124        uint32_t h = ctx->H[7];
00125 
00126        /* First increment the byte count.  FIPS 180-2 specifies the possible
00127         length of the file up to 2^64 bits.  Here we only compute the
00128         number of bytes.  Do a double word increment.  */
00129        ctx->total[0] += len;
00130        if (ctx->total[0] < len) {
00131               ++ctx->total[1];
00132        }
00133 
00134        /* Process all bytes in the buffer with 64 bytes in each round of
00135         the loop.  */
00136        while (nwords > 0) {
00137               uint32_t W[64];
00138               uint32_t a_save = a;
00139               uint32_t b_save = b;
00140               uint32_t c_save = c;
00141               uint32_t d_save = d;
00142               uint32_t e_save = e;
00143               uint32_t f_save = f;
00144               uint32_t g_save = g;
00145               uint32_t h_save = h;
00146 
00147        /* Operators defined in FIPS 180-2:4.1.2.  */
00148 #define Ch(x, y, z) ((x & y) ^ (~x & z))
00149 #define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
00150 #define S0(x) (CYCLIC (x, 2) ^ CYCLIC (x, 13) ^ CYCLIC (x, 22))
00151 #define S1(x) (CYCLIC (x, 6) ^ CYCLIC (x, 11) ^ CYCLIC (x, 25))
00152 #define R0(x) (CYCLIC (x, 7) ^ CYCLIC (x, 18) ^ (x >> 3))
00153 #define R1(x) (CYCLIC (x, 17) ^ CYCLIC (x, 19) ^ (x >> 10))
00154 
00155        /* It is unfortunate that C does not provide an operator for
00156        cyclic rotation.  Hope the C compiler is smart enough.  */
00157 #define CYCLIC(w, s) ((w >> s) | (w << (32 - s)))
00158 
00159               /* Compute the message schedule according to FIPS 180-2:6.2.2 step 2.  */
00160               for (t = 0; t < 16; ++t) {
00161                      W[t] = SWAP (*words);
00162                      ++words;
00163               }
00164               for (t = 16; t < 64; ++t)
00165                      W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
00166 
00167               /* The actual computation according to FIPS 180-2:6.2.2 step 3.  */
00168               for (t = 0; t < 64; ++t) {
00169                      uint32_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
00170                      uint32_t T2 = S0 (a) + Maj (a, b, c);
00171                      h = g;
00172                      g = f;
00173                      f = e;
00174                      e = d + T1;
00175                      d = c;
00176                      c = b;
00177                      b = a;
00178                      a = T1 + T2;
00179               }
00180 
00181               /* Add the starting values of the context according to FIPS 180-2:6.2.2
00182               step 4.  */
00183               a += a_save;
00184               b += b_save;
00185               c += c_save;
00186               d += d_save;
00187               e += e_save;
00188               f += f_save;
00189               g += g_save;
00190               h += h_save;
00191 
00192               /* Prepare for the next round.  */
00193               nwords -= 16;
00194        }
00195 
00196        /* Put checksum in context given as argument.  */
00197        ctx->H[0] = a;
00198        ctx->H[1] = b;
00199        ctx->H[2] = c;
00200        ctx->H[3] = d;
00201        ctx->H[4] = e;
00202        ctx->H[5] = f;
00203        ctx->H[6] = g;
00204        ctx->H[7] = h;
00205 }
00206 
00207 
00208 /* Initialize structure containing state of computation.
00209    (FIPS 180-2:5.3.2)  */
00210 static void sha256_init_ctx(struct sha256_ctx *ctx) {
00211        ctx->H[0] = 0x6a09e667;
00212        ctx->H[1] = 0xbb67ae85;
00213        ctx->H[2] = 0x3c6ef372;
00214        ctx->H[3] = 0xa54ff53a;
00215        ctx->H[4] = 0x510e527f;
00216        ctx->H[5] = 0x9b05688c;
00217        ctx->H[6] = 0x1f83d9ab;
00218        ctx->H[7] = 0x5be0cd19;
00219 
00220        ctx->total[0] = ctx->total[1] = 0;
00221        ctx->buflen = 0;
00222 }
00223 
00224 
00225 /* Process the remaining bytes in the internal buffer and the usual
00226    prolog according to the standard and write the result to RESBUF.
00227 
00228    IMPORTANT: On some systems it is required that RESBUF is correctly
00229    aligned for a 32 bits value.  */
00230 static void * sha256_finish_ctx(struct sha256_ctx *ctx, void *resbuf) {
00231        /* Take yet unprocessed bytes into account.  */
00232        uint32_t bytes = ctx->buflen;
00233        size_t pad;
00234        unsigned int i;
00235 
00236        /* Now count remaining bytes.  */
00237        ctx->total[0] += bytes;
00238        if (ctx->total[0] < bytes) {
00239               ++ctx->total[1];
00240        }
00241 
00242        pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
00243        memcpy(&ctx->buffer[bytes], fillbuf, pad);
00244 
00245        /* Put the 64-bit file length in *bits* at the end of the buffer.  */
00246        *(uint32_t *) &ctx->buffer[bytes + pad + 4] = SWAP (ctx->total[0] << 3);
00247        *(uint32_t *) &ctx->buffer[bytes + pad] = SWAP ((ctx->total[1] << 3) |
00248                                             (ctx->total[0] >> 29));
00249 
00250        /* Process last bytes.  */
00251        sha256_process_block(ctx->buffer, bytes + pad + 8, ctx);
00252 
00253        /* Put result from CTX in first 32 bytes following RESBUF.  */
00254        for (i = 0; i < 8; ++i) {
00255               ((uint32_t *) resbuf)[i] = SWAP(ctx->H[i]);
00256        }
00257 
00258        return resbuf;
00259 }
00260 
00261 
00262 static void sha256_process_bytes(const void *buffer, size_t len, struct sha256_ctx *ctx) {
00263        /* When we already have some bits in our internal buffer concatenate
00264         both inputs first.  */
00265        if (ctx->buflen != 0) {
00266               size_t left_over = ctx->buflen;
00267               size_t add = 128 - left_over > len ? len : 128 - left_over;
00268 
00269                 memcpy(&ctx->buffer[left_over], buffer, add);
00270                 ctx->buflen += add;
00271 
00272               if (ctx->buflen > 64) {
00273                      sha256_process_block(ctx->buffer, ctx->buflen & ~63, ctx);
00274                      ctx->buflen &= 63;
00275                      /* The regions in the following copy operation cannot overlap.  */
00276                      memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~63], ctx->buflen);
00277               }
00278 
00279               buffer = (const char *) buffer + add;
00280               len -= add;
00281        }
00282 
00283        /* Process available complete blocks.  */
00284        if (len >= 64) {
00285 /* To check alignment gcc has an appropriate operator.  Other
00286 compilers don't.  */
00287 #if __GNUC__ >= 2
00288 # define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0)
00289 #else
00290 # define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0)
00291 #endif
00292               if (UNALIGNED_P (buffer))
00293                      while (len > 64) {
00294                             sha256_process_block(memcpy(ctx->buffer, buffer, 64), 64, ctx);
00295                             buffer = (const char *) buffer + 64;
00296                             len -= 64;
00297                      } else {
00298                             sha256_process_block(buffer, len & ~63, ctx);
00299                             buffer = (const char *) buffer + (len & ~63);
00300                             len &= 63;
00301                      }
00302        }
00303 
00304        /* Move remaining bytes into internal buffer.  */
00305        if (len > 0) {
00306               size_t left_over = ctx->buflen;
00307 
00308               memcpy(&ctx->buffer[left_over], buffer, len);
00309               left_over += len;
00310               if (left_over >= 64) {
00311                      sha256_process_block(ctx->buffer, 64, ctx);
00312                      left_over -= 64;
00313                      memcpy(ctx->buffer, &ctx->buffer[64], left_over);
00314               }
00315               ctx->buflen = left_over;
00316        }
00317 }
00318 
00319 
00320 /* Define our magic string to mark salt for SHA256 "encryption"
00321    replacement.  */
00322 static const char sha256_salt_prefix[] = "$5$";
00323 
00324 /* Prefix for optional rounds specification.  */
00325 static const char sha256_rounds_prefix[] = "rounds=";
00326 
00327 /* Maximum salt string length.  */
00328 #define SALT_LEN_MAX 16
00329 /* Default number of rounds if not explicitly specified.  */
00330 #define ROUNDS_DEFAULT 5000
00331 /* Minimum number of rounds.  */
00332 #define ROUNDS_MIN 1000
00333 /* Maximum number of rounds.  */
00334 #define ROUNDS_MAX 999999999
00335 
00336 /* Table with characters for base64 transformation.  */
00337 static const char b64t[64] =
00338 "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
00339 
00340 char * php_sha256_crypt_r(const char *key, const char *salt, char *buffer, int buflen)
00341 {
00342 #ifdef PHP_WIN32
00343 # if _MSC <= 1300
00344 #  pragma pack(push, 16)
00345        unsigned char alt_result[32];
00346        unsigned char temp_result[32];
00347 #  pragma pack(pop)
00348 # else
00349        __declspec(align(32)) unsigned char alt_result[32];
00350        __declspec(align(32)) unsigned char temp_result[32];
00351 # endif
00352 #else
00353        unsigned char alt_result[32] ALIGNED(__alignof__ (uint32_t));
00354        unsigned char temp_result[32] ALIGNED(__alignof__ (uint32_t));
00355 #endif
00356 
00357        struct sha256_ctx ctx;
00358        struct sha256_ctx alt_ctx;
00359        size_t salt_len;
00360        size_t key_len;
00361        size_t cnt;
00362        char *cp;
00363        char *copied_key = NULL;
00364        char *copied_salt = NULL;
00365        char *p_bytes;
00366        char *s_bytes;
00367        /* Default number of rounds.  */
00368        size_t rounds = ROUNDS_DEFAULT;
00369        zend_bool rounds_custom = 0;
00370 
00371        /* Find beginning of salt string.  The prefix should normally always
00372        be present.  Just in case it is not.  */
00373        if (strncmp(sha256_salt_prefix, salt, sizeof(sha256_salt_prefix) - 1) == 0) {
00374               /* Skip salt prefix.  */
00375               salt += sizeof(sha256_salt_prefix) - 1;
00376        }
00377 
00378        if (strncmp(salt, sha256_rounds_prefix, sizeof(sha256_rounds_prefix) - 1) == 0) {
00379               const char *num = salt + sizeof(sha256_rounds_prefix) - 1;
00380               char *endp;
00381               unsigned long int srounds = strtoul(num, &endp, 10);
00382               if (*endp == '$') {
00383                      salt = endp + 1;
00384                      rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
00385                      rounds_custom = 1;
00386               }
00387        }
00388 
00389        salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
00390        key_len = strlen(key);
00391 
00392        if ((key - (char *) 0) % __alignof__ (uint32_t) != 0) {
00393               char *tmp = (char *) alloca(key_len + __alignof__(uint32_t));
00394               key = copied_key = memcpy(tmp + __alignof__(uint32_t) - (tmp - (char *) 0) % __alignof__(uint32_t), key, key_len);
00395        }
00396 
00397        if ((salt - (char *) 0) % __alignof__(uint32_t) != 0) {
00398               char *tmp = (char *) alloca(salt_len + 1 + __alignof__(uint32_t));
00399               salt = copied_salt =
00400               memcpy(tmp + __alignof__(uint32_t) - (tmp - (char *) 0) % __alignof__ (uint32_t), salt, salt_len);
00401               copied_salt[salt_len] = 0;
00402        }
00403 
00404        /* Prepare for the real work.  */
00405        sha256_init_ctx(&ctx);
00406 
00407        /* Add the key string.  */
00408        sha256_process_bytes(key, key_len, &ctx);
00409 
00410        /* The last part is the salt string.  This must be at most 16
00411         characters and it ends at the first `$' character (for
00412         compatibility with existing implementations).  */
00413        sha256_process_bytes(salt, salt_len, &ctx);
00414 
00415 
00416        /* Compute alternate SHA256 sum with input KEY, SALT, and KEY.  The
00417         final result will be added to the first context.  */
00418        sha256_init_ctx(&alt_ctx);
00419 
00420        /* Add key.  */
00421        sha256_process_bytes(key, key_len, &alt_ctx);
00422 
00423        /* Add salt.  */
00424        sha256_process_bytes(salt, salt_len, &alt_ctx);
00425 
00426        /* Add key again.  */
00427        sha256_process_bytes(key, key_len, &alt_ctx);
00428 
00429        /* Now get result of this (32 bytes) and add it to the other
00430         context.  */
00431        sha256_finish_ctx(&alt_ctx, alt_result);
00432 
00433        /* Add for any character in the key one byte of the alternate sum.  */
00434        for (cnt = key_len; cnt > 32; cnt -= 32) {
00435               sha256_process_bytes(alt_result, 32, &ctx);
00436        }
00437        sha256_process_bytes(alt_result, cnt, &ctx);
00438 
00439        /* Take the binary representation of the length of the key and for every
00440        1 add the alternate sum, for every 0 the key.  */
00441        for (cnt = key_len; cnt > 0; cnt >>= 1) {
00442               if ((cnt & 1) != 0) {
00443                      sha256_process_bytes(alt_result, 32, &ctx);
00444               } else {
00445                      sha256_process_bytes(key, key_len, &ctx);
00446               }
00447        }
00448 
00449        /* Create intermediate result.  */
00450        sha256_finish_ctx(&ctx, alt_result);
00451 
00452        /* Start computation of P byte sequence.  */
00453        sha256_init_ctx(&alt_ctx);
00454 
00455        /* For every character in the password add the entire password.  */
00456        for (cnt = 0; cnt < key_len; ++cnt) {
00457               sha256_process_bytes(key, key_len, &alt_ctx);
00458        }
00459 
00460        /* Finish the digest.  */
00461        sha256_finish_ctx(&alt_ctx, temp_result);
00462 
00463        /* Create byte sequence P.  */
00464        cp = p_bytes = alloca(key_len);
00465        for (cnt = key_len; cnt >= 32; cnt -= 32) {
00466               cp = __php_mempcpy((void *)cp, (const void *)temp_result, 32);
00467        }
00468        memcpy(cp, temp_result, cnt);
00469 
00470        /* Start computation of S byte sequence.  */
00471        sha256_init_ctx(&alt_ctx);
00472 
00473        /* For every character in the password add the entire password.  */
00474        for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt) {
00475               sha256_process_bytes(salt, salt_len, &alt_ctx);
00476        }
00477 
00478        /* Finish the digest.  */
00479        sha256_finish_ctx(&alt_ctx, temp_result);
00480 
00481        /* Create byte sequence S.  */
00482        cp = s_bytes = alloca(salt_len);
00483        for (cnt = salt_len; cnt >= 32; cnt -= 32) {
00484               cp = __php_mempcpy(cp, temp_result, 32);
00485        }
00486        memcpy(cp, temp_result, cnt);
00487 
00488        /* Repeatedly run the collected hash value through SHA256 to burn
00489        CPU cycles.  */
00490        for (cnt = 0; cnt < rounds; ++cnt) {
00491               /* New context.  */
00492               sha256_init_ctx(&ctx);
00493 
00494               /* Add key or last result.  */
00495               if ((cnt & 1) != 0) {
00496                      sha256_process_bytes(p_bytes, key_len, &ctx);
00497               } else {
00498                      sha256_process_bytes(alt_result, 32, &ctx);
00499               }
00500 
00501               /* Add salt for numbers not divisible by 3.  */
00502               if (cnt % 3 != 0) {
00503                      sha256_process_bytes(s_bytes, salt_len, &ctx);
00504               }
00505 
00506               /* Add key for numbers not divisible by 7.  */
00507               if (cnt % 7 != 0) {
00508                      sha256_process_bytes(p_bytes, key_len, &ctx);
00509               }
00510 
00511               /* Add key or last result.  */
00512               if ((cnt & 1) != 0) {
00513                      sha256_process_bytes(alt_result, 32, &ctx);
00514               } else {
00515                      sha256_process_bytes(p_bytes, key_len, &ctx);
00516               }
00517 
00518               /* Create intermediate result.  */
00519               sha256_finish_ctx(&ctx, alt_result);
00520        }
00521 
00522        /* Now we can construct the result string.  It consists of three
00523        parts.  */
00524        cp = __php_stpncpy(buffer, sha256_salt_prefix, MAX(0, buflen));
00525        buflen -= sizeof(sha256_salt_prefix) - 1;
00526 
00527        if (rounds_custom) {
00528 #ifdef PHP_WIN32
00529               int n = _snprintf(cp, MAX(0, buflen), "%s%u$", sha256_rounds_prefix, rounds);
00530 #else
00531               int n = snprintf(cp, MAX(0, buflen), "%s%zu$", sha256_rounds_prefix, rounds);
00532 #endif
00533               cp += n;
00534               buflen -= n;
00535        }
00536 
00537        cp = __php_stpncpy(cp, salt, MIN ((size_t) MAX (0, buflen), salt_len));
00538        buflen -= MIN((size_t) MAX (0, buflen), salt_len);
00539 
00540        if (buflen > 0) {
00541               *cp++ = '$';
00542               --buflen;
00543        }
00544 
00545 #define b64_from_24bit(B2, B1, B0, N)                                       \
00546   do {                                                               \
00547     unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0);                     \
00548     int n = (N);                                                     \
00549     while (n-- > 0 && buflen > 0)                                    \
00550       {                                                                     \
00551        *cp++ = b64t[w & 0x3f];                                              \
00552        --buflen;                                                     \
00553        w >>= 6;                                                      \
00554       }                                                                     \
00555   } while (0)
00556 
00557        b64_from_24bit(alt_result[0], alt_result[10], alt_result[20], 4);
00558        b64_from_24bit(alt_result[21], alt_result[1], alt_result[11], 4);
00559        b64_from_24bit(alt_result[12], alt_result[22], alt_result[2], 4);
00560        b64_from_24bit(alt_result[3], alt_result[13], alt_result[23], 4);
00561        b64_from_24bit(alt_result[24], alt_result[4], alt_result[14], 4);
00562        b64_from_24bit(alt_result[15], alt_result[25], alt_result[5], 4);
00563        b64_from_24bit(alt_result[6], alt_result[16], alt_result[26], 4);
00564        b64_from_24bit(alt_result[27], alt_result[7], alt_result[17], 4);
00565        b64_from_24bit(alt_result[18], alt_result[28], alt_result[8], 4);
00566        b64_from_24bit(alt_result[9], alt_result[19], alt_result[29], 4);
00567        b64_from_24bit(0, alt_result[31], alt_result[30], 3);
00568        if (buflen <= 0) {
00569               errno = ERANGE;
00570               buffer = NULL;
00571        } else
00572               *cp = '\0';          /* Terminate the string.  */
00573 
00574        /* Clear the buffer for the intermediate result so that people
00575      attaching to processes or reading core dumps cannot get any
00576      information.  We do it in this way to clear correct_words[]
00577      inside the SHA256 implementation as well.  */
00578        sha256_init_ctx(&ctx);
00579        sha256_finish_ctx(&ctx, alt_result);
00580        memset(temp_result, '\0', sizeof(temp_result));
00581        memset(p_bytes, '\0', key_len);
00582        memset(s_bytes, '\0', salt_len);
00583        memset(&ctx, '\0', sizeof(ctx));
00584        memset(&alt_ctx, '\0', sizeof(alt_ctx));
00585 
00586        if (copied_key != NULL) {
00587               memset(copied_key, '\0', key_len);
00588 
00589        }
00590        if (copied_salt != NULL) {
00591               memset(copied_salt, '\0', salt_len);
00592        }
00593 
00594        return buffer;
00595 }
00596 
00597 
00598 /* This entry point is equivalent to the `crypt' function in Unix
00599    libcs.  */
00600 char * php_sha256_crypt(const char *key, const char *salt)
00601 {
00602        /* We don't want to have an arbitrary limit in the size of the
00603        password.  We can compute an upper bound for the size of the
00604        result in advance and so we can prepare the buffer we pass to
00605        `sha256_crypt_r'.  */
00606        static char *buffer;
00607        static int buflen;
00608        int needed = (sizeof(sha256_salt_prefix) - 1
00609                      + sizeof(sha256_rounds_prefix) + 9 + 1
00610                      + strlen(salt) + 1 + 43 + 1);
00611 
00612        if (buflen < needed) {
00613               char *new_buffer = (char *) realloc(buffer, needed);
00614               if (new_buffer == NULL) {
00615                      return NULL;
00616               }
00617 
00618               buffer = new_buffer;
00619               buflen = needed;
00620        }
00621 
00622        return php_sha256_crypt_r(key, salt, buffer, buflen);
00623 }
00624 
00625 
00626 #ifdef TEST
00627 static const struct
00628 {
00629        const char *input;
00630        const char result[32];
00631 } tests[] =
00632        {
00633        /* Test vectors from FIPS 180-2: appendix B.1.  */
00634        { "abc",
00635        "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23"
00636        "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" },
00637        /* Test vectors from FIPS 180-2: appendix B.2.  */
00638        { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
00639        "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
00640        "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
00641        /* Test vectors from the NESSIE project.  */
00642        { "",
00643        "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9\x24"
00644        "\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52\xb8\x55" },
00645        { "a",
00646        "\xca\x97\x81\x12\xca\x1b\xbd\xca\xfa\xc2\x31\xb3\x9a\x23\xdc\x4d"
00647        "\xa7\x86\xef\xf8\x14\x7c\x4e\x72\xb9\x80\x77\x85\xaf\xee\x48\xbb" },
00648        { "message digest",
00649        "\xf7\x84\x6f\x55\xcf\x23\xe1\x4e\xeb\xea\xb5\xb4\xe1\x55\x0c\xad"
00650        "\x5b\x50\x9e\x33\x48\xfb\xc4\xef\xa3\xa1\x41\x3d\x39\x3c\xb6\x50" },
00651        { "abcdefghijklmnopqrstuvwxyz",
00652        "\x71\xc4\x80\xdf\x93\xd6\xae\x2f\x1e\xfa\xd1\x44\x7c\x66\xc9\x52"
00653        "\x5e\x31\x62\x18\xcf\x51\xfc\x8d\x9e\xd8\x32\xf2\xda\xf1\x8b\x73" },
00654        { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
00655        "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39"
00656        "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" },
00657        { "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
00658        "\xdb\x4b\xfc\xbd\x4d\xa0\xcd\x85\xa6\x0c\x3c\x37\xd3\xfb\xd8\x80"
00659        "\x5c\x77\xf1\x5f\xc6\xb1\xfd\xfe\x61\x4e\xe0\xa7\xc8\xfd\xb4\xc0" },
00660        { "123456789012345678901234567890123456789012345678901234567890"
00661        "12345678901234567890",
00662        "\xf3\x71\xbc\x4a\x31\x1f\x2b\x00\x9e\xef\x95\x2d\xd8\x3c\xa8\x0e"
00663        "\x2b\x60\x02\x6c\x8e\x93\x55\x92\xd0\xf9\xc3\x08\x45\x3c\x81\x3e" }
00664   };
00665 #define ntests (sizeof (tests) / sizeof (tests[0]))
00666 
00667 
00668 static const struct
00669 {
00670        const char *salt;
00671        const char *input;
00672        const char *expected;
00673 } tests2[] =
00674 {
00675        { "$5$saltstring", "Hello world!",
00676        "$5$saltstring$5B8vYYiY.CVt1RlTTf8KbXBH3hsxY/GNooZaBBGWEc5" },
00677        { "$5$rounds=10000$saltstringsaltstring", "Hello world!",
00678        "$5$rounds=10000$saltstringsaltst$3xv.VbSHBb41AL9AvLeujZkZRBAwqFMz2."
00679        "opqey6IcA" },
00680        { "$5$rounds=5000$toolongsaltstring", "This is just a test",
00681        "$5$rounds=5000$toolongsaltstrin$Un/5jzAHMgOGZ5.mWJpuVolil07guHPvOW8"
00682        "mGRcvxa5" },
00683        { "$5$rounds=1400$anotherlongsaltstring",
00684        "a very much longer text to encrypt.  This one even stretches over more"
00685        "than one line.",
00686        "$5$rounds=1400$anotherlongsalts$Rx.j8H.h8HjEDGomFU8bDkXm3XIUnzyxf12"
00687        "oP84Bnq1" },
00688        { "$5$rounds=77777$short",
00689        "we have a short salt string but not a short password",
00690        "$5$rounds=77777$short$JiO1O3ZpDAxGJeaDIuqCoEFysAe1mZNJRs3pw0KQRd/" },
00691        { "$5$rounds=123456$asaltof16chars..", "a short string",
00692        "$5$rounds=123456$asaltof16chars..$gP3VQ/6X7UUEW3HkBn2w1/Ptq2jxPyzV/"
00693        "cZKmF/wJvD" },
00694        { "$5$rounds=10$roundstoolow", "the minimum number is still observed",
00695        "$5$rounds=1000$roundstoolow$yfvwcWrQ8l/K0DAWyuPMDNHpIVlTQebY9l/gL97"
00696        "2bIC" },
00697 };
00698 #define ntests2 (sizeof (tests2) / sizeof (tests2[0]))
00699 
00700 
00701 int main(void) {
00702        struct sha256_ctx ctx;
00703        char sum[32];
00704        int result = 0;
00705        int cnt, i;
00706        char buf[1000];
00707        static const char expected[32] =
00708        "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67"
00709        "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0";
00710 
00711        for (cnt = 0; cnt < (int) ntests; ++cnt) {
00712               sha256_init_ctx(&ctx);
00713               sha256_process_bytes(tests[cnt].input, strlen(tests[cnt].input), &ctx);
00714               sha256_finish_ctx(&ctx, sum);
00715               if (memcmp(tests[cnt].result, sum, 32) != 0) {
00716                      printf("test %d run %d failed\n", cnt, 1);
00717                      result = 1;
00718               }
00719 
00720               sha256_init_ctx(&ctx);
00721               for (i = 0; tests[cnt].input[i] != '\0'; ++i) {
00722                      sha256_process_bytes(&tests[cnt].input[i], 1, &ctx);
00723               }
00724               sha256_finish_ctx(&ctx, sum);
00725               if (memcmp(tests[cnt].result, sum, 32) != 0) {
00726                      printf("test %d run %d failed\n", cnt, 2);
00727                      result = 1;
00728               }
00729        }
00730 
00731        /* Test vector from FIPS 180-2: appendix B.3.  */
00732 
00733        memset(buf, 'a', sizeof(buf));
00734        sha256_init_ctx(&ctx);
00735        for (i = 0; i < 1000; ++i) {
00736               sha256_process_bytes (buf, sizeof (buf), &ctx);
00737        }
00738 
00739        sha256_finish_ctx(&ctx, sum);
00740 
00741        if (memcmp(expected, sum, 32) != 0) {
00742               printf("test %d failed\n", cnt);
00743               result = 1;
00744        }
00745 
00746        for (cnt = 0; cnt < ntests2; ++cnt) {
00747               char *cp = php_sha256_crypt(tests2[cnt].input, tests2[cnt].salt);
00748               if (strcmp(cp, tests2[cnt].expected) != 0) {
00749                      printf("test %d: expected \"%s\", got \"%s\"\n", cnt, tests2[cnt].expected, cp);
00750                      result = 1;
00751               }
00752        }
00753 
00754        if (result == 0)
00755        puts("all tests OK");
00756 
00757        return result;
00758 }
00759 #endif