Annotation of embedaddon/php/ext/standard/crypt_sha256.c, revision 1.1.1.2

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

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>