Back to index

php5  5.3.10
Classes | Defines | Functions | Variables
crypt_sha512.c File Reference
#include "php.h"
#include "php_main.h"
#include <errno.h>
#include <limits.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/param.h>
#include <sys/types.h>
#include <strings.h>

Go to the source code of this file.

Classes

struct  sha512_ctx

Defines

#define __alignof__(type)   offsetof (struct { char c; type member;}, member)
#define ALIGNED(size)
#define MIN(a, b)   (((a) < (b)) ? (a) : (b))
#define MAX(a, b)   (((a) > (b)) ? (a) : (b))
#define UINT64_C(value)   __CONCAT(value, ULL)
#define SWAP(n)
#define Ch(x, y, z)   ((x & y) ^ (~x & z))
#define Maj(x, y, z)   ((x & y) ^ (x & z) ^ (y & z))
#define S0(x)   (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39))
#define S1(x)   (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41))
#define R0(x)   (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
#define R1(x)   (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))
#define CYCLIC(w, s)   ((w >> s) | (w << (64 - s)))
#define UNALIGNED_P(p)   (((uintptr_t) p) % sizeof(uint64_t) != 0)
#define SALT_LEN_MAX   16
#define ROUNDS_DEFAULT   5000
#define ROUNDS_MIN   1000
#define ROUNDS_MAX   999999999
#define b64_from_24bit(B2, B1, B0, N)

Functions

void * __php_mempcpy (void *dst, const void *src, size_t len)
char * __php_stpncpy (char *dst, const char *src, size_t len)
static void sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
static void sha512_init_ctx (struct sha512_ctx *ctx)
static void * sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
static void sha512_process_bytes (const void *buffer, size_t len, struct sha512_ctx *ctx)
char * php_sha512_crypt_r (const char *key, const char *salt, char *buffer, int buflen)
char * php_sha512_crypt (const char *key, const char *salt)

Variables

static const unsigned char fillbuf [128] = { 0x80, 0 }
static const uint64_t K [80]
static const char sha512_salt_prefix [] = "$6$"
static const char sha512_rounds_prefix [] = "rounds="
static const char b64t [64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"

Class Documentation

struct sha512_ctx

Definition at line 62 of file crypt_sha512.c.

Class Members
char buffer
uint64_t buflen
uint64_t H
uint64_t total

Define Documentation

#define __alignof__ (   type)    offsetof (struct { char c; type member;}, member)

Definition at line 22 of file crypt_sha512.c.

#define ALIGNED (   size)

Definition at line 27 of file crypt_sha512.c.

#define b64_from_24bit (   B2,
  B1,
  B0,
  N 
)
Value:
do {                                                                            \
       unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0);      \
       int n = (N);                                                         \
       while (n-- > 0 && buflen > 0)                                       \
         {                                                                             \
       *cp++ = b64t[w & 0x3f];                                                 \
       --buflen;                                                                \
       w >>= 6;                                                                 \
         }                                                                             \
  } while (0)
#define Ch (   x,
  y,
 
)    ((x & y) ^ (~x & z))
#define CYCLIC (   w,
 
)    ((w >> s) | (w << (64 - s)))
#define Maj (   x,
  y,
 
)    ((x & y) ^ (x & z) ^ (y & z))
#define MAX (   a,
 
)    (((a) > (b)) ? (a) : (b))

Definition at line 53 of file crypt_sha512.c.

#define MIN (   a,
 
)    (((a) < (b)) ? (a) : (b))

Definition at line 50 of file crypt_sha512.c.

#define R0 (   x)    (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
#define R1 (   x)    (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))
#define ROUNDS_DEFAULT   5000

Definition at line 363 of file crypt_sha512.c.

#define ROUNDS_MAX   999999999

Definition at line 367 of file crypt_sha512.c.

#define ROUNDS_MIN   1000

Definition at line 365 of file crypt_sha512.c.

#define S0 (   x)    (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39))
#define S1 (   x)    (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41))
#define SALT_LEN_MAX   16

Definition at line 361 of file crypt_sha512.c.

#define SWAP (   n)
Value:
(((n) << 56)                              \
   | (((n) & 0xff00) << 40)               \
   | (((n) & 0xff0000) << 24)                    \
   | (((n) & 0xff000000) << 8)                   \
   | (((n) >> 8) & 0xff000000)                   \
   | (((n) >> 24) & 0xff0000)                    \
   | (((n) >> 40) & 0xff00)               \
   | ((n) >> 56))

Definition at line 73 of file crypt_sha512.c.

#define UINT64_C (   value)    __CONCAT(value, ULL)

Definition at line 58 of file crypt_sha512.c.

#define UNALIGNED_P (   p)    (((uintptr_t) p) % sizeof(uint64_t) != 0)

Function Documentation

void* __php_mempcpy ( void *  dst,
const void *  src,
size_t  len 
)

Definition at line 56 of file crypt_sha256.c.

{
       return (((char *)memcpy(dst, src, len)) + len);
}

Here is the caller graph for this function:

char* __php_stpncpy ( char *  dst,
const char *  src,
size_t  len 
)

Definition at line 47 of file crypt_sha256.c.

{
       size_t n = strlen(src);
       if (n > len) {
              n = len;
       }
       return strncpy(dst, src, len) + n;
}

Here is the caller graph for this function:

char* php_sha512_crypt ( const char *  key,
const char *  salt 
)

Definition at line 647 of file crypt_sha512.c.

                                                    {
       /* We don't want to have an arbitrary limit in the size of the
        password.  We can compute an upper bound for the size of the
        result in advance and so we can prepare the buffer we pass to
        `sha512_crypt_r'.  */
       static char *buffer;
       static int buflen;
       int needed = (int)(sizeof(sha512_salt_prefix) - 1
              + sizeof(sha512_rounds_prefix) + 9 + 1
              + strlen(salt) + 1 + 86 + 1);

       if (buflen < needed) {
              char *new_buffer = (char *) realloc(buffer, needed);
              if (new_buffer == NULL) {
                     return NULL;
              }

              buffer = new_buffer;
              buflen = needed;
       }

       return php_sha512_crypt_r (key, salt, buffer, buflen);
}

Here is the call graph for this function:

char* php_sha512_crypt_r ( const char *  key,
const char *  salt,
char *  buffer,
int  buflen 
)

Definition at line 375 of file crypt_sha512.c.

                                                                                {
#ifdef PHP_WIN32
# if _MSC <= 1300
#  pragma pack(push, 16)
       unsigned char alt_result[64];
       unsigned char temp_result[64];
#  pragma pack(pop)
# else
       __declspec(align(64)) unsigned char alt_result[64];
       __declspec(align(64)) unsigned char temp_result[64];
# endif
#else
       unsigned char alt_result[64] ALIGNED(__alignof__ (uint64_t));
       unsigned char temp_result[64] ALIGNED(__alignof__ (uint64_t));
#endif
       struct sha512_ctx ctx;
       struct sha512_ctx alt_ctx;
       size_t salt_len;
       size_t key_len;
       size_t cnt;
       char *cp;
       char *copied_key = NULL;
       char *copied_salt = NULL;
       char *p_bytes;
       char *s_bytes;
       /* Default number of rounds.  */
       size_t rounds = ROUNDS_DEFAULT;
       zend_bool rounds_custom = 0;

       /* Find beginning of salt string.  The prefix should normally always
        be present.  Just in case it is not.  */
       if (strncmp(sha512_salt_prefix, salt, sizeof(sha512_salt_prefix) - 1) == 0) {
              /* Skip salt prefix.  */
              salt += sizeof(sha512_salt_prefix) - 1;
       }

       if (strncmp(salt, sha512_rounds_prefix, sizeof(sha512_rounds_prefix) - 1) == 0) {
              const char *num = salt + sizeof(sha512_rounds_prefix) - 1;
              char *endp;
              unsigned long int srounds = strtoul(num, &endp, 10);

              if (*endp == '$') {
                     salt = endp + 1;
                     rounds = MAX(ROUNDS_MIN, MIN(srounds, ROUNDS_MAX));
                     rounds_custom = 1;
              }
       }

       salt_len = MIN(strcspn(salt, "$"), SALT_LEN_MAX);
       key_len = strlen(key);

       if ((key - (char *) 0) % __alignof__ (uint64_t) != 0) {
              char *tmp = (char *) alloca (key_len + __alignof__ (uint64_t));
              key = copied_key =
              memcpy(tmp + __alignof__(uint64_t) - (tmp - (char *) 0) % __alignof__(uint64_t), key, key_len);
       }

       if ((salt - (char *) 0) % __alignof__ (uint64_t) != 0) {
              char *tmp = (char *) alloca(salt_len + 1 + __alignof__(uint64_t));
              salt = copied_salt = memcpy(tmp + __alignof__(uint64_t) - (tmp - (char *) 0) % __alignof__(uint64_t), salt, salt_len);
              copied_salt[salt_len] = 0;
       }

       /* Prepare for the real work.  */
       sha512_init_ctx(&ctx);

       /* Add the key string.  */
       sha512_process_bytes(key, key_len, &ctx);

       /* The last part is the salt string.  This must be at most 16
        characters and it ends at the first `$' character (for
        compatibility with existing implementations).  */
       sha512_process_bytes(salt, salt_len, &ctx);


       /* Compute alternate SHA512 sum with input KEY, SALT, and KEY.  The
        final result will be added to the first context.  */
       sha512_init_ctx(&alt_ctx);

       /* Add key.  */
       sha512_process_bytes(key, key_len, &alt_ctx);

       /* Add salt.  */
       sha512_process_bytes(salt, salt_len, &alt_ctx);

       /* Add key again.  */
       sha512_process_bytes(key, key_len, &alt_ctx);

       /* Now get result of this (64 bytes) and add it to the other
        context.  */
       sha512_finish_ctx(&alt_ctx, alt_result);

       /* Add for any character in the key one byte of the alternate sum.  */
       for (cnt = key_len; cnt > 64; cnt -= 64) {
              sha512_process_bytes(alt_result, 64, &ctx);
       }
       sha512_process_bytes(alt_result, cnt, &ctx);

       /* Take the binary representation of the length of the key and for every
        1 add the alternate sum, for every 0 the key.  */
       for (cnt = key_len; cnt > 0; cnt >>= 1) {
              if ((cnt & 1) != 0) {
                     sha512_process_bytes(alt_result, 64, &ctx);
              } else {
                     sha512_process_bytes(key, key_len, &ctx);
              }
       }

       /* Create intermediate result.  */
       sha512_finish_ctx(&ctx, alt_result);

       /* Start computation of P byte sequence.  */
       sha512_init_ctx(&alt_ctx);

       /* For every character in the password add the entire password.  */
       for (cnt = 0; cnt < key_len; ++cnt) {
              sha512_process_bytes(key, key_len, &alt_ctx);
       }

       /* Finish the digest.  */
       sha512_finish_ctx(&alt_ctx, temp_result);

       /* Create byte sequence P.  */
       cp = p_bytes = alloca(key_len);
       for (cnt = key_len; cnt >= 64; cnt -= 64) {
              cp = __php_mempcpy((void *) cp, (const void *)temp_result, 64);
       }

       memcpy(cp, temp_result, cnt);

       /* Start computation of S byte sequence.  */
       sha512_init_ctx(&alt_ctx);

       /* For every character in the password add the entire password.  */
       for (cnt = 0; cnt < 16 + alt_result[0]; ++cnt) {
              sha512_process_bytes(salt, salt_len, &alt_ctx);
       }

       /* Finish the digest.  */
       sha512_finish_ctx(&alt_ctx, temp_result);

       /* Create byte sequence S.  */
       cp = s_bytes = alloca(salt_len);
       for (cnt = salt_len; cnt >= 64; cnt -= 64) {
              cp = __php_mempcpy(cp, temp_result, 64);
       }
       memcpy(cp, temp_result, cnt);

       /* Repeatedly run the collected hash value through SHA512 to burn
        CPU cycles.  */
       for (cnt = 0; cnt < rounds; ++cnt) {
              /* New context.  */
              sha512_init_ctx(&ctx);

              /* Add key or last result.  */
              if ((cnt & 1) != 0) {
                     sha512_process_bytes(p_bytes, key_len, &ctx);
              } else {
                     sha512_process_bytes(alt_result, 64, &ctx);
              }

              /* Add salt for numbers not divisible by 3.  */
              if (cnt % 3 != 0) {
                     sha512_process_bytes(s_bytes, salt_len, &ctx);
              }

              /* Add key for numbers not divisible by 7.  */
              if (cnt % 7 != 0) {
                     sha512_process_bytes(p_bytes, key_len, &ctx);
              }

              /* Add key or last result.  */
              if ((cnt & 1) != 0) {
                     sha512_process_bytes(alt_result, 64, &ctx);
              } else {
                     sha512_process_bytes(p_bytes, key_len, &ctx);
              }

              /* Create intermediate result.  */
              sha512_finish_ctx(&ctx, alt_result);
       }

       /* Now we can construct the result string.  It consists of three
        parts.  */
       cp = __php_stpncpy(buffer, sha512_salt_prefix, MAX(0, buflen));
       buflen -= sizeof(sha512_salt_prefix) - 1;

       if (rounds_custom) {
#ifdef PHP_WIN32
         int n = _snprintf(cp, MAX(0, buflen), "%s%u$", sha512_rounds_prefix, rounds);
#else
         int n = snprintf(cp, MAX(0, buflen), "%s%zu$", sha512_rounds_prefix, rounds);
#endif
         cp += n;
         buflen -= n;
       }

       cp = __php_stpncpy(cp, salt, MIN((size_t) MAX(0, buflen), salt_len));
       buflen -= (int) MIN((size_t) MAX(0, buflen), salt_len);

       if (buflen > 0) {
              *cp++ = '$';
              --buflen;
       }

#define b64_from_24bit(B2, B1, B0, N)                    \
  do {                                                                          \
       unsigned int w = ((B2) << 16) | ((B1) << 8) | (B0);      \
       int n = (N);                                                         \
       while (n-- > 0 && buflen > 0)                                       \
         {                                                                             \
       *cp++ = b64t[w & 0x3f];                                                 \
       --buflen;                                                                \
       w >>= 6;                                                                 \
         }                                                                             \
  } while (0)

       b64_from_24bit(alt_result[0], alt_result[21], alt_result[42], 4);
       b64_from_24bit(alt_result[22], alt_result[43], alt_result[1], 4);
       b64_from_24bit(alt_result[44], alt_result[2], alt_result[23], 4);
       b64_from_24bit(alt_result[3], alt_result[24], alt_result[45], 4);
       b64_from_24bit(alt_result[25], alt_result[46], alt_result[4], 4);
       b64_from_24bit(alt_result[47], alt_result[5], alt_result[26], 4);
       b64_from_24bit(alt_result[6], alt_result[27], alt_result[48], 4);
       b64_from_24bit(alt_result[28], alt_result[49], alt_result[7], 4);
       b64_from_24bit(alt_result[50], alt_result[8], alt_result[29], 4);
       b64_from_24bit(alt_result[9], alt_result[30], alt_result[51], 4);
       b64_from_24bit(alt_result[31], alt_result[52], alt_result[10], 4);
       b64_from_24bit(alt_result[53], alt_result[11], alt_result[32], 4);
       b64_from_24bit(alt_result[12], alt_result[33], alt_result[54], 4);
       b64_from_24bit(alt_result[34], alt_result[55], alt_result[13], 4);
       b64_from_24bit(alt_result[56], alt_result[14], alt_result[35], 4);
       b64_from_24bit(alt_result[15], alt_result[36], alt_result[57], 4);
       b64_from_24bit(alt_result[37], alt_result[58], alt_result[16], 4);
       b64_from_24bit(alt_result[59], alt_result[17], alt_result[38], 4);
       b64_from_24bit(alt_result[18], alt_result[39], alt_result[60], 4);
       b64_from_24bit(alt_result[40], alt_result[61], alt_result[19], 4);
       b64_from_24bit(alt_result[62], alt_result[20], alt_result[41], 4);
       b64_from_24bit(0, 0, alt_result[63], 2);

       if (buflen <= 0) {
              errno = ERANGE;
              buffer = NULL;
       } else {
              *cp = '\0';          /* Terminate the string.  */
       }

       /* Clear the buffer for the intermediate result so that people
        attaching to processes or reading core dumps cannot get any
        information.  We do it in this way to clear correct_words[]
        inside the SHA512 implementation as well.  */
       sha512_init_ctx(&ctx);
       sha512_finish_ctx(&ctx, alt_result);
       memset(temp_result, '\0', sizeof(temp_result));
       memset(p_bytes, '\0', key_len);
       memset(s_bytes, '\0', salt_len);
       memset(&ctx, '\0', sizeof(ctx));
       memset(&alt_ctx, '\0', sizeof(alt_ctx));
       if (copied_key != NULL) {
              memset(copied_key, '\0', key_len);
       }
       if (copied_salt != NULL) {
              memset(copied_salt, '\0', salt_len);
       }

       return buffer;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void* sha512_finish_ctx ( struct sha512_ctx ctx,
void *  resbuf 
) [static]

Definition at line 257 of file crypt_sha512.c.

                                                                       {
       /* Take yet unprocessed bytes into account.  */
       uint64_t bytes = ctx->buflen;
       size_t pad;
       unsigned int i;

       /* Now count remaining bytes.  */
       ctx->total[0] += bytes;
       if (ctx->total[0] < bytes) {
              ++ctx->total[1];
       }

       pad = bytes >= 112 ? 128 + 112 - (size_t)bytes : 112 - (size_t)bytes;
       memcpy(&ctx->buffer[bytes], fillbuf, pad);

       /* Put the 128-bit file length in *bits* at the end of the buffer.  */
       *(uint64_t *) &ctx->buffer[bytes + pad + 8] = SWAP(ctx->total[0] << 3);
       *(uint64_t *) &ctx->buffer[bytes + pad] = SWAP((ctx->total[1] << 3) |
                                          (ctx->total[0] >> 61));

       /* Process last bytes.  */
       sha512_process_block(ctx->buffer, (size_t)(bytes + pad + 16), ctx);

       /* Put result from CTX in first 64 bytes following RESBUF.  */
       for (i = 0; i < 8; ++i) {
              ((uint64_t *) resbuf)[i] = SWAP(ctx->H[i]);
       }

       return resbuf;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sha512_init_ctx ( struct sha512_ctx ctx) [static]

Definition at line 237 of file crypt_sha512.c.

                                                     {
       ctx->H[0] = UINT64_C (0x6a09e667f3bcc908);
       ctx->H[1] = UINT64_C (0xbb67ae8584caa73b);
       ctx->H[2] = UINT64_C (0x3c6ef372fe94f82b);
       ctx->H[3] = UINT64_C (0xa54ff53a5f1d36f1);
       ctx->H[4] = UINT64_C (0x510e527fade682d1);
       ctx->H[5] = UINT64_C (0x9b05688c2b3e6c1f);
       ctx->H[6] = UINT64_C (0x1f83d9abfb41bd6b);
       ctx->H[7] = UINT64_C (0x5be0cd19137e2179);

       ctx->total[0] = ctx->total[1] = 0;
       ctx->buflen = 0;
}

Here is the caller graph for this function:

static void sha512_process_block ( const void *  buffer,
size_t  len,
struct sha512_ctx ctx 
) [static]

Definition at line 138 of file crypt_sha512.c.

                                                                             {
       const uint64_t *words = buffer;
       size_t nwords = len / sizeof(uint64_t);
       uint64_t a = ctx->H[0];
       uint64_t b = ctx->H[1];
       uint64_t c = ctx->H[2];
       uint64_t d = ctx->H[3];
       uint64_t e = ctx->H[4];
       uint64_t f = ctx->H[5];
       uint64_t g = ctx->H[6];
       uint64_t h = ctx->H[7];

  /* First increment the byte count.  FIPS 180-2 specifies the possible
        length of the file up to 2^128 bits.  Here we only compute the
        number of bytes.  Do a double word increment.  */
       ctx->total[0] += len;
       if (ctx->total[0] < len) {
              ++ctx->total[1];
       }

       /* Process all bytes in the buffer with 128 bytes in each round of
        the loop.  */
       while (nwords > 0) {
              uint64_t W[80];
              uint64_t a_save = a;
              uint64_t b_save = b;
              uint64_t c_save = c;
              uint64_t d_save = d;
              uint64_t e_save = e;
              uint64_t f_save = f;
              uint64_t g_save = g;
              uint64_t h_save = h;
              unsigned int t;

/* Operators defined in FIPS 180-2:4.1.2.  */
#define Ch(x, y, z) ((x & y) ^ (~x & z))
#define Maj(x, y, z) ((x & y) ^ (x & z) ^ (y & z))
#define S0(x) (CYCLIC (x, 28) ^ CYCLIC (x, 34) ^ CYCLIC (x, 39))
#define S1(x) (CYCLIC (x, 14) ^ CYCLIC (x, 18) ^ CYCLIC (x, 41))
#define R0(x) (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
#define R1(x) (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))

              /* It is unfortunate that C does not provide an operator for
                 cyclic rotation.  Hope the C compiler is smart enough.  */
#define CYCLIC(w, s) ((w >> s) | (w << (64 - s)))

              /* Compute the message schedule according to FIPS 180-2:6.3.2 step 2.  */
              for (t = 0; t < 16; ++t) {
                     W[t] = SWAP (*words);
                     ++words;
              }

              for (t = 16; t < 80; ++t) {
                     W[t] = R1 (W[t - 2]) + W[t - 7] + R0 (W[t - 15]) + W[t - 16];
              }

              /* The actual computation according to FIPS 180-2:6.3.2 step 3.  */
              for (t = 0; t < 80; ++t) {
                     uint64_t T1 = h + S1 (e) + Ch (e, f, g) + K[t] + W[t];
                     uint64_t T2 = S0 (a) + Maj (a, b, c);
                     h = g;
                     g = f;
                     f = e;
                     e = d + T1;
                     d = c;
                     c = b;
                     b = a;
                     a = T1 + T2;
              }

              /* Add the starting values of the context according to FIPS 180-2:6.3.2
              step 4.  */
              a += a_save;
              b += b_save;
              c += c_save;
              d += d_save;
              e += e_save;
              f += f_save;
              g += g_save;
              h += h_save;

              /* Prepare for the next round.  */
              nwords -= 16;
       }

       /* Put checksum in context given as argument.  */
       ctx->H[0] = a;
       ctx->H[1] = b;
       ctx->H[2] = c;
       ctx->H[3] = d;
       ctx->H[4] = e;
       ctx->H[5] = f;
       ctx->H[6] = g;
       ctx->H[7] = h;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void sha512_process_bytes ( const void *  buffer,
size_t  len,
struct sha512_ctx ctx 
) [static]

Definition at line 289 of file crypt_sha512.c.

                                                                             {
       /* When we already have some bits in our internal buffer concatenate
        both inputs first.  */
       if (ctx->buflen != 0) {
              size_t left_over = (size_t)ctx->buflen;
              size_t add = (size_t)(256 - left_over > len ? len : 256 - left_over);

              memcpy(&ctx->buffer[left_over], buffer, add);
              ctx->buflen += add;

              if (ctx->buflen > 128) {
                     sha512_process_block(ctx->buffer, ctx->buflen & ~127, ctx);

                     ctx->buflen &= 127;
                     /* The regions in the following copy operation cannot overlap.  */
                     memcpy(ctx->buffer, &ctx->buffer[(left_over + add) & ~127],
                                   (size_t)ctx->buflen);
              }

              buffer = (const char *) buffer + add;
              len -= add;
       }

       /* Process available complete blocks.  */
       if (len >= 128) {
#if !_STRING_ARCH_unaligned
/* To check alignment gcc has an appropriate operator.  Other
   compilers don't.  */
# if __GNUC__ >= 2
#  define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint64_t) != 0)
# else
#  define UNALIGNED_P(p) (((uintptr_t) p) % sizeof(uint64_t) != 0)
# endif
              if (UNALIGNED_P(buffer))
                     while (len > 128) {
                            sha512_process_block(memcpy(ctx->buffer, buffer, 128), 128, ctx);
                            buffer = (const char *) buffer + 128;
                            len -= 128;
                     }
              else
#endif
              {
                sha512_process_block(buffer, len & ~127, ctx);
                buffer = (const char *) buffer + (len & ~127);
                len &= 127;
              }
       }

  /* Move remaining bytes into internal buffer.  */
       if (len > 0) {
              size_t left_over = (size_t)ctx->buflen;

              memcpy(&ctx->buffer[left_over], buffer, len);
              left_over += len;
              if (left_over >= 128) {
                     sha512_process_block(ctx->buffer, 128, ctx);
                     left_over -= 128;
                     memcpy(ctx->buffer, &ctx->buffer[128], left_over);
              }
              ctx->buflen = left_over;
       }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

const char b64t[64] = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" [static]

Definition at line 370 of file crypt_sha512.c.

const unsigned char fillbuf[128] = { 0x80, 0 } [static]

Definition at line 88 of file crypt_sha512.c.

const uint64_t K[80] [static]

Definition at line 91 of file crypt_sha512.c.

const char sha512_rounds_prefix[] = "rounds=" [static]

Definition at line 358 of file crypt_sha512.c.

const char sha512_salt_prefix[] = "$6$" [static]

Definition at line 355 of file crypt_sha512.c.