Back to index

glibc  2.9
Defines | Functions | Variables
sha512.c File Reference
#include <endian.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include "sha512.h"

Go to the source code of this file.

Defines

#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)

Functions

static void sha512_process_block (const void *buffer, size_t len, struct sha512_ctx *ctx)
void __sha512_init_ctx (struct sha512_ctx *ctx)
void * __sha512_finish_ctx (struct sha512_ctx *ctx, void *resbuf)
void __sha512_process_bytes (void *buffer, size_t len, struct sha512_ctx *ctx) const

Variables

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

Define Documentation

#define Ch (   x,
  y,
  z 
)    ((x & y) ^ (~x & z))
#define CYCLIC (   w,
  s 
)    ((w >> s) | (w << (64 - s)))
#define Maj (   x,
  y,
  z 
)    ((x & y) ^ (x & z) ^ (y & z))
#define R0 (   x)    (CYCLIC (x, 1) ^ CYCLIC (x, 8) ^ (x >> 7))
#define R1 (   x)    (CYCLIC (x, 19) ^ CYCLIC (x, 61) ^ (x >> 6))
#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 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 39 of file sha512.c.

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

Function Documentation

void* __sha512_finish_ctx ( struct sha512_ctx ctx,
void *  resbuf 
)

Definition at line 231 of file sha512.c.

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

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

  pad = bytes >= 112 ? 128 + 112 - bytes : 112 - 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, bytes + pad + 16, ctx);

  /* Put result from CTX in first 64 bytes following RESBUF.  */
  for (unsigned int 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:

void __sha512_init_ctx ( struct sha512_ctx ctx)

Definition at line 208 of file 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:

void __sha512_process_bytes ( void *  buffer,
size_t  len,
struct sha512_ctx ctx 
) const

Definition at line 264 of file sha512.c.

{
  /* When we already have some bits in our internal buffer concatenate
     both inputs first.  */
  if (ctx->buflen != 0)
    {
      size_t left_over = ctx->buflen;
      size_t add = 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],
                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 = 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:

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

Definition at line 108 of file 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;

      /* 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 (unsigned int t = 0; t < 16; ++t)
       {
         W[t] = SWAP (*words);
         ++words;
       }
      for (unsigned int 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 (unsigned int 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 caller graph for this function:


Variable Documentation

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

Definition at line 56 of file sha512.c.

const uint64_t K[80] [static]

Definition at line 60 of file sha512.c.