Blame crypt/sha256.c

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