Blame crypt/sha256.c

Packit 6c4009
/* Functions to compute SHA256 message digest of files or memory blocks.
Packit 6c4009
   according to the definition of SHA256 in FIPS 180-2.
Packit 6c4009
   Copyright (C) 2007-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
/* Written by Ulrich Drepper <drepper@redhat.com>, 2007.  */
Packit 6c4009
Packit 6c4009
#ifdef HAVE_CONFIG_H
Packit 6c4009
# include <config.h>
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
#include <endian.h>
Packit 6c4009
#include <stdlib.h>
Packit 6c4009
#include <string.h>
Packit 6c4009
#include <stdint.h>
Packit 6c4009
#include <sys/types.h>
Packit 6c4009
Packit 6c4009
#include "sha256.h"
Packit 6c4009
Packit 6c4009
#if __BYTE_ORDER == __LITTLE_ENDIAN
Packit 6c4009
# ifdef _LIBC
Packit 6c4009
#  include <byteswap.h>
Packit 6c4009
#  define SWAP(n) bswap_32 (n)
Packit 6c4009
#  define SWAP64(n) bswap_64 (n)
Packit 6c4009
# else
Packit 6c4009
#  define SWAP(n) \
Packit 6c4009
    (((n) << 24) | (((n) & 0xff00) << 8) | (((n) >> 8) & 0xff00) | ((n) >> 24))
Packit 6c4009
#  define SWAP64(n) \
Packit 6c4009
  (((n) << 56)					\
Packit 6c4009
   | (((n) & 0xff00) << 40)			\
Packit 6c4009
   | (((n) & 0xff0000) << 24)			\
Packit 6c4009
   | (((n) & 0xff000000) << 8)			\
Packit 6c4009
   | (((n) >> 8) & 0xff000000)			\
Packit 6c4009
   | (((n) >> 24) & 0xff0000)			\
Packit 6c4009
   | (((n) >> 40) & 0xff00)			\
Packit 6c4009
   | ((n) >> 56))
Packit 6c4009
# endif
Packit 6c4009
#else
Packit 6c4009
# define SWAP(n) (n)
Packit 6c4009
# define SWAP64(n) (n)
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* This array contains the bytes used to pad the buffer to the next
Packit 6c4009
   64-byte boundary.  (FIPS 180-2:5.1.1)  */
Packit 6c4009
static const unsigned char fillbuf[64] = { 0x80, 0 /* , 0, 0, ...  */ };
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Constants for SHA256 from FIPS 180-2:4.2.2.  */
Packit 6c4009
static const uint32_t K[64] =
Packit 6c4009
  {
Packit 6c4009
    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
Packit 6c4009
    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
Packit 6c4009
    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
Packit 6c4009
    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
Packit 6c4009
    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
Packit 6c4009
    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
Packit 6c4009
    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
Packit 6c4009
    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
Packit 6c4009
    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
Packit 6c4009
    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
Packit 6c4009
    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
Packit 6c4009
    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
Packit 6c4009
    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
Packit 6c4009
    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
Packit 6c4009
    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
Packit 6c4009
    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
Packit 6c4009
  };
Packit 6c4009
Packit 6c4009
void __sha256_process_block (const void *, size_t, struct sha256_ctx *);
Packit 6c4009
Packit 6c4009
/* Initialize structure containing state of computation.
Packit 6c4009
   (FIPS 180-2:5.3.2)  */
Packit 6c4009
void
Packit 6c4009
__sha256_init_ctx (struct sha256_ctx *ctx)
Packit 6c4009
{
Packit 6c4009
  ctx->H[0] = 0x6a09e667;
Packit 6c4009
  ctx->H[1] = 0xbb67ae85;
Packit 6c4009
  ctx->H[2] = 0x3c6ef372;
Packit 6c4009
  ctx->H[3] = 0xa54ff53a;
Packit 6c4009
  ctx->H[4] = 0x510e527f;
Packit 6c4009
  ctx->H[5] = 0x9b05688c;
Packit 6c4009
  ctx->H[6] = 0x1f83d9ab;
Packit 6c4009
  ctx->H[7] = 0x5be0cd19;
Packit 6c4009
Packit 6c4009
  ctx->total64 = 0;
Packit 6c4009
  ctx->buflen = 0;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
/* Process the remaining bytes in the internal buffer and the usual
Packit 6c4009
   prolog according to the standard and write the result to RESBUF.
Packit 6c4009
Packit 6c4009
   IMPORTANT: On some systems it is required that RESBUF is correctly
Packit 6c4009
   aligned for a 32 bits value.  */
Packit 6c4009
void *
Packit 6c4009
__sha256_finish_ctx (struct sha256_ctx *ctx, void *resbuf)
Packit 6c4009
{
Packit 6c4009
  /* Take yet unprocessed bytes into account.  */
Packit 6c4009
  uint32_t bytes = ctx->buflen;
Packit 6c4009
  size_t pad;
Packit 6c4009
Packit 6c4009
  /* Now count remaining bytes.  */
Packit 6c4009
  ctx->total64 += bytes;
Packit 6c4009
Packit 6c4009
  pad = bytes >= 56 ? 64 + 56 - bytes : 56 - bytes;
Packit 6c4009
  memcpy (&ctx->buffer[bytes], fillbuf, pad);
Packit 6c4009
Packit 6c4009
  /* Put the 64-bit file length in *bits* at the end of the buffer.  */
Packit 6c4009
#if _STRING_ARCH_unaligned
Packit 6c4009
  ctx->buffer64[(bytes + pad) / 8] = SWAP64 (ctx->total64 << 3);
Packit 6c4009
#else
Packit 6c4009
  ctx->buffer32[(bytes + pad + 4) / 4] = SWAP (ctx->total[TOTAL64_low] << 3);
Packit 6c4009
  ctx->buffer32[(bytes + pad) / 4] = SWAP ((ctx->total[TOTAL64_high] << 3) |
Packit 6c4009
					   (ctx->total[TOTAL64_low] >> 29));
Packit 6c4009
#endif
Packit 6c4009
Packit 6c4009
  /* Process last bytes.  */
Packit 6c4009
  __sha256_process_block (ctx->buffer, bytes + pad + 8, ctx);
Packit 6c4009
Packit 6c4009
  /* Put result from CTX in first 32 bytes following RESBUF.  */
Packit 6c4009
  for (unsigned int i = 0; i < 8; ++i)
Packit 6c4009
    ((uint32_t *) resbuf)[i] = SWAP (ctx->H[i]);
Packit 6c4009
Packit 6c4009
  return resbuf;
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
Packit 6c4009
void
Packit 6c4009
__sha256_process_bytes (const void *buffer, size_t len, struct sha256_ctx *ctx)
Packit 6c4009
{
Packit 6c4009
  /* When we already have some bits in our internal buffer concatenate
Packit 6c4009
     both inputs first.  */
Packit 6c4009
  if (ctx->buflen != 0)
Packit 6c4009
    {
Packit 6c4009
      size_t left_over = ctx->buflen;
Packit 6c4009
      size_t add = 128 - left_over > len ? len : 128 - left_over;
Packit 6c4009
Packit 6c4009
      memcpy (&ctx->buffer[left_over], buffer, add);
Packit 6c4009
      ctx->buflen += add;
Packit 6c4009
Packit 6c4009
      if (ctx->buflen > 64)
Packit 6c4009
	{
Packit 6c4009
	  __sha256_process_block (ctx->buffer, ctx->buflen & ~63, ctx);
Packit 6c4009
Packit 6c4009
	  ctx->buflen &= 63;
Packit 6c4009
	  /* The regions in the following copy operation cannot overlap.  */
Packit 6c4009
	  memcpy (ctx->buffer, &ctx->buffer[(left_over + add) & ~63],
Packit 6c4009
		  ctx->buflen);
Packit 6c4009
	}
Packit 6c4009
Packit 6c4009
      buffer = (const char *) buffer + add;
Packit 6c4009
      len -= add;
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Process available complete blocks.  */
Packit 6c4009
  if (len >= 64)
Packit 6c4009
    {
Packit 6c4009
#if !_STRING_ARCH_unaligned
Packit 6c4009
/* To check alignment gcc has an appropriate operator.  Other
Packit 6c4009
   compilers don't.  */
Packit 6c4009
# if __GNUC__ >= 2
Packit 6c4009
#  define UNALIGNED_P(p) (((uintptr_t) p) % __alignof__ (uint32_t) != 0)
Packit 6c4009
# else
Packit 6c4009
#  define UNALIGNED_P(p) (((uintptr_t) p) % sizeof (uint32_t) != 0)
Packit 6c4009
# endif
Packit 6c4009
      if (UNALIGNED_P (buffer))
Packit 6c4009
	while (len > 64)
Packit 6c4009
	  {
Packit 6c4009
	    __sha256_process_block (memcpy (ctx->buffer, buffer, 64), 64, ctx);
Packit 6c4009
	    buffer = (const char *) buffer + 64;
Packit 6c4009
	    len -= 64;
Packit 6c4009
	  }
Packit 6c4009
      else
Packit 6c4009
#endif
Packit 6c4009
	{
Packit 6c4009
	  __sha256_process_block (buffer, len & ~63, ctx);
Packit 6c4009
	  buffer = (const char *) buffer + (len & ~63);
Packit 6c4009
	  len &= 63;
Packit 6c4009
	}
Packit 6c4009
    }
Packit 6c4009
Packit 6c4009
  /* Move remaining bytes into internal buffer.  */
Packit 6c4009
  if (len > 0)
Packit 6c4009
    {
Packit 6c4009
      size_t left_over = ctx->buflen;
Packit 6c4009
Packit 6c4009
      memcpy (&ctx->buffer[left_over], buffer, len);
Packit 6c4009
      left_over += len;
Packit 6c4009
      if (left_over >= 64)
Packit 6c4009
	{
Packit 6c4009
	  __sha256_process_block (ctx->buffer, 64, ctx);
Packit 6c4009
	  left_over -= 64;
Packit 6c4009
	  memcpy (ctx->buffer, &ctx->buffer[64], left_over);
Packit 6c4009
	}
Packit 6c4009
      ctx->buflen = left_over;
Packit 6c4009
    }
Packit 6c4009
}
Packit 6c4009
Packit 6c4009
#include <sha256-block.c>