Blame alg-sha1.c

Packit 13e0ca
/*
Packit 13e0ca
SHA-1 in C
Packit 13e0ca
By Steve Reid <sreid@sea-to-sky.net>
Packit 13e0ca
100% Public Domain
Packit 13e0ca
Packit 13e0ca
-----------------
Packit 13e0ca
Modified 7/98
Packit 13e0ca
By James H. Brown <jbrown@burgoyne.com>
Packit 13e0ca
Still 100% Public Domain
Packit 13e0ca
Packit 13e0ca
Corrected a problem which generated improper hash values on 16 bit machines
Packit 13e0ca
Routine SHA1Update changed from
Packit 13e0ca
  void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len)
Packit 13e0ca
to
Packit 13e0ca
  void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned long len)
Packit 13e0ca
Packit 13e0ca
The 'len' parameter was declared an int which works fine on 32 bit machines.
Packit 13e0ca
However, on 16 bit machines an int is too small for the shifts being done
Packit 13e0ca
against
Packit 13e0ca
it.  This caused the hash function to generate incorrect values if len was
Packit 13e0ca
greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
Packit 13e0ca
Packit 13e0ca
Since the file IO in main() reads 16K at a time, any file 8K or larger would
Packit 13e0ca
be guaranteed to generate the wrong hash (e.g. Test Vector #3,
Packit 13e0ca
a million "a"s).
Packit 13e0ca
Packit 13e0ca
I also changed the declaration of variables i & j in SHA1Update to
Packit 13e0ca
unsigned long from unsigned int for the same reason.
Packit 13e0ca
Packit 13e0ca
These changes should make no difference to any 32 bit implementations since
Packit 13e0ca
an int and a long are the same size in those environments.
Packit 13e0ca
Packit 13e0ca
--
Packit 13e0ca
I also corrected a few compiler warnings generated by Borland C.
Packit 13e0ca
1. Added #include <process.h> for exit() prototype
Packit 13e0ca
2. Removed unused variable 'j' in SHA1Final
Packit 13e0ca
3. Changed exit(0) to return(0) at end of main.
Packit 13e0ca
Packit 13e0ca
ALL changes I made can be located by searching for comments containing 'JHB'
Packit 13e0ca
-----------------
Packit 13e0ca
Modified 8/98
Packit 13e0ca
By Steve Reid <sreid@sea-to-sky.net>
Packit 13e0ca
Still 100% public domain
Packit 13e0ca
Packit 13e0ca
1- Removed #include <process.h> and used return() instead of exit()
Packit 13e0ca
2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
Packit 13e0ca
3- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net
Packit 13e0ca
Packit 13e0ca
-----------------
Packit 13e0ca
Modified 4/01
Packit 13e0ca
By Saul Kravitz <Saul.Kravitz@celera.com>
Packit 13e0ca
Still 100% PD
Packit 13e0ca
Modified to run on Compaq Alpha hardware.
Packit 13e0ca
Packit 13e0ca
-----------------
Packit 13e0ca
Modified 07/2002
Packit 13e0ca
By Ralph Giles <giles@ghostscript.com>
Packit 13e0ca
Still 100% public domain
Packit 13e0ca
modified for use with stdint types, autoconf
Packit 13e0ca
code cleanup, removed attribution comments
Packit 13e0ca
switched SHA1Final() argument order for consistency
Packit 13e0ca
use SHA1_ prefix for public api
Packit 13e0ca
move public api to sha1.h
Packit 13e0ca
Packit 13e0ca
-----------------
Packit 13e0ca
Modified 10/2017
Packit 13e0ca
By Björn Esser <besser82@fedoraproject.org>
Packit 13e0ca
Still 100% public domain
Packit 13e0ca
modified for use with libxcrypt
Packit 13e0ca
*/
Packit 13e0ca
Packit 13e0ca
#include "crypt-port.h"
Packit 13e0ca
#include "alg-sha1.h"
Packit 13e0ca
Packit 13e0ca
#if INCLUDE_sha1
Packit 13e0ca
Packit 13e0ca
#define SHA1_DIGEST_SIZE 20
Packit 13e0ca
Packit 13e0ca
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
Packit 13e0ca
Packit 13e0ca
/* blk0() and blk() perform the initial expand. */
Packit 13e0ca
/* I got the idea of expanding during the round function from SSLeay */
Packit 13e0ca
/* FIXME: can we do this in an endian-proof way? */
Packit 13e0ca
#if IS_BIGENDIAN
Packit 13e0ca
#define blk0(i) block.l[i]
Packit 13e0ca
#else
Packit 13e0ca
#define blk0(i) (block.l[i] = (rol(block.l[i],24)&0xFF00FF00) \
Packit 13e0ca
    |(rol(block.l[i],8)&0x00FF00FF))
Packit 13e0ca
#endif
Packit 13e0ca
#define blk(i) (block.l[i&15] = rol(block.l[(i+13)&15]^block.l[(i+8)&15] \
Packit 13e0ca
    ^block.l[(i+2)&15]^block.l[i&15],1))
Packit 13e0ca
Packit 13e0ca
/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
Packit 13e0ca
#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
Packit 13e0ca
#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
Packit 13e0ca
#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
Packit 13e0ca
#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
Packit 13e0ca
#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
Packit 13e0ca
Packit 13e0ca
Packit 13e0ca
/* Hash a single 512-bit block. This is the core of the algorithm. */
Packit 13e0ca
static void
Packit 13e0ca
sha1_do_transform (uint32_t state[5], const uint8_t buffer[64])
Packit 13e0ca
{
Packit 13e0ca
  uint32_t a, b, c, d, e;
Packit 13e0ca
  typedef union
Packit 13e0ca
  {
Packit 13e0ca
    uint8_t c[64];
Packit 13e0ca
    uint32_t l[16];
Packit 13e0ca
  } CHAR64LONG16;
Packit 13e0ca
  CHAR64LONG16 block;
Packit 13e0ca
Packit 13e0ca
  memcpy (&block, buffer, 64);
Packit 13e0ca
Packit 13e0ca
  /* Copy context->state[] to working vars */
Packit 13e0ca
  a = state[0];
Packit 13e0ca
  b = state[1];
Packit 13e0ca
  c = state[2];
Packit 13e0ca
  d = state[3];
Packit 13e0ca
  e = state[4];
Packit 13e0ca
Packit 13e0ca
  /* 4 rounds of 20 operations each. Loop unrolled. */
Packit 13e0ca
  R0(a,b,c,d,e, 0);
Packit 13e0ca
  R0(e,a,b,c,d, 1);
Packit 13e0ca
  R0(d,e,a,b,c, 2);
Packit 13e0ca
  R0(c,d,e,a,b, 3);
Packit 13e0ca
  R0(b,c,d,e,a, 4);
Packit 13e0ca
  R0(a,b,c,d,e, 5);
Packit 13e0ca
  R0(e,a,b,c,d, 6);
Packit 13e0ca
  R0(d,e,a,b,c, 7);
Packit 13e0ca
  R0(c,d,e,a,b, 8);
Packit 13e0ca
  R0(b,c,d,e,a, 9);
Packit 13e0ca
  R0(a,b,c,d,e,10);
Packit 13e0ca
  R0(e,a,b,c,d,11);
Packit 13e0ca
  R0(d,e,a,b,c,12);
Packit 13e0ca
  R0(c,d,e,a,b,13);
Packit 13e0ca
  R0(b,c,d,e,a,14);
Packit 13e0ca
  R0(a,b,c,d,e,15);
Packit 13e0ca
  R1(e,a,b,c,d,16);
Packit 13e0ca
  R1(d,e,a,b,c,17);
Packit 13e0ca
  R1(c,d,e,a,b,18);
Packit 13e0ca
  R1(b,c,d,e,a,19);
Packit 13e0ca
  R2(a,b,c,d,e,20);
Packit 13e0ca
  R2(e,a,b,c,d,21);
Packit 13e0ca
  R2(d,e,a,b,c,22);
Packit 13e0ca
  R2(c,d,e,a,b,23);
Packit 13e0ca
  R2(b,c,d,e,a,24);
Packit 13e0ca
  R2(a,b,c,d,e,25);
Packit 13e0ca
  R2(e,a,b,c,d,26);
Packit 13e0ca
  R2(d,e,a,b,c,27);
Packit 13e0ca
  R2(c,d,e,a,b,28);
Packit 13e0ca
  R2(b,c,d,e,a,29);
Packit 13e0ca
  R2(a,b,c,d,e,30);
Packit 13e0ca
  R2(e,a,b,c,d,31);
Packit 13e0ca
  R2(d,e,a,b,c,32);
Packit 13e0ca
  R2(c,d,e,a,b,33);
Packit 13e0ca
  R2(b,c,d,e,a,34);
Packit 13e0ca
  R2(a,b,c,d,e,35);
Packit 13e0ca
  R2(e,a,b,c,d,36);
Packit 13e0ca
  R2(d,e,a,b,c,37);
Packit 13e0ca
  R2(c,d,e,a,b,38);
Packit 13e0ca
  R2(b,c,d,e,a,39);
Packit 13e0ca
  R3(a,b,c,d,e,40);
Packit 13e0ca
  R3(e,a,b,c,d,41);
Packit 13e0ca
  R3(d,e,a,b,c,42);
Packit 13e0ca
  R3(c,d,e,a,b,43);
Packit 13e0ca
  R3(b,c,d,e,a,44);
Packit 13e0ca
  R3(a,b,c,d,e,45);
Packit 13e0ca
  R3(e,a,b,c,d,46);
Packit 13e0ca
  R3(d,e,a,b,c,47);
Packit 13e0ca
  R3(c,d,e,a,b,48);
Packit 13e0ca
  R3(b,c,d,e,a,49);
Packit 13e0ca
  R3(a,b,c,d,e,50);
Packit 13e0ca
  R3(e,a,b,c,d,51);
Packit 13e0ca
  R3(d,e,a,b,c,52);
Packit 13e0ca
  R3(c,d,e,a,b,53);
Packit 13e0ca
  R3(b,c,d,e,a,54);
Packit 13e0ca
  R3(a,b,c,d,e,55);
Packit 13e0ca
  R3(e,a,b,c,d,56);
Packit 13e0ca
  R3(d,e,a,b,c,57);
Packit 13e0ca
  R3(c,d,e,a,b,58);
Packit 13e0ca
  R3(b,c,d,e,a,59);
Packit 13e0ca
  R4(a,b,c,d,e,60);
Packit 13e0ca
  R4(e,a,b,c,d,61);
Packit 13e0ca
  R4(d,e,a,b,c,62);
Packit 13e0ca
  R4(c,d,e,a,b,63);
Packit 13e0ca
  R4(b,c,d,e,a,64);
Packit 13e0ca
  R4(a,b,c,d,e,65);
Packit 13e0ca
  R4(e,a,b,c,d,66);
Packit 13e0ca
  R4(d,e,a,b,c,67);
Packit 13e0ca
  R4(c,d,e,a,b,68);
Packit 13e0ca
  R4(b,c,d,e,a,69);
Packit 13e0ca
  R4(a,b,c,d,e,70);
Packit 13e0ca
  R4(e,a,b,c,d,71);
Packit 13e0ca
  R4(d,e,a,b,c,72);
Packit 13e0ca
  R4(c,d,e,a,b,73);
Packit 13e0ca
  R4(b,c,d,e,a,74);
Packit 13e0ca
  R4(a,b,c,d,e,75);
Packit 13e0ca
  R4(e,a,b,c,d,76);
Packit 13e0ca
  R4(d,e,a,b,c,77);
Packit 13e0ca
  R4(c,d,e,a,b,78);
Packit 13e0ca
  R4(b,c,d,e,a,79);
Packit 13e0ca
Packit 13e0ca
  /* Add the working vars back into context.state[] */
Packit 13e0ca
  state[0] += a;
Packit 13e0ca
  state[1] += b;
Packit 13e0ca
  state[2] += c;
Packit 13e0ca
  state[3] += d;
Packit 13e0ca
  state[4] += e;
Packit 13e0ca
Packit 13e0ca
  /* Wipe variables */
Packit 13e0ca
  a = b = c = d = e = 0;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
Packit 13e0ca
/* SHA1Init - Initialize new context */
Packit 13e0ca
void
Packit 13e0ca
sha1_init_ctx (struct sha1_ctx* ctx)
Packit 13e0ca
{
Packit 13e0ca
  /* SHA1 initialization constants */
Packit 13e0ca
  ctx->state[0] = 0x67452301;
Packit 13e0ca
  ctx->state[1] = 0xEFCDAB89;
Packit 13e0ca
  ctx->state[2] = 0x98BADCFE;
Packit 13e0ca
  ctx->state[3] = 0x10325476;
Packit 13e0ca
  ctx->state[4] = 0xC3D2E1F0;
Packit 13e0ca
  ctx->count[0] = ctx->count[1] = 0;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
Packit 13e0ca
/* Run your data through this. */
Packit 13e0ca
void
Packit 13e0ca
sha1_process_bytes (const void *buffer, struct sha1_ctx *ctx, size_t size)
Packit 13e0ca
{
Packit 13e0ca
  size_t i, j;
Packit 13e0ca
Packit 13e0ca
  j = (ctx->count[0] >> 3) & 63;
Packit 13e0ca
  if ((ctx->count[0] += (uint32_t)size << 3) < ((uint32_t)size << 3)) ctx->count[1]++;
Packit 13e0ca
  ctx->count[1] += (uint32_t)(size >> 29);
Packit 13e0ca
  if ((j + size) > 63)
Packit 13e0ca
    {
Packit 13e0ca
      memcpy (&ctx->buffer[j], buffer, (i = 64-j));
Packit 13e0ca
      sha1_do_transform (ctx->state, ctx->buffer);
Packit 13e0ca
      for ( ; i + 63 < size; i += 64)
Packit 13e0ca
        sha1_do_transform (ctx->state, (const uint8_t*)buffer + i);
Packit 13e0ca
      j = 0;
Packit 13e0ca
    }
Packit 13e0ca
  else i = 0;
Packit 13e0ca
  memcpy (&ctx->buffer[j], (const uint8_t *)buffer + i, size - i);
Packit 13e0ca
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
Packit 13e0ca
/* Add padding and return the message digest. */
Packit 13e0ca
void *
Packit 13e0ca
sha1_finish_ctx (struct sha1_ctx *ctx, void *resbuf)
Packit 13e0ca
{
Packit 13e0ca
  uint32_t i;
Packit 13e0ca
  uint8_t  finalcount[8];
Packit 13e0ca
Packit 13e0ca
  for (i = 0; i < 8; i++)
Packit 13e0ca
    {
Packit 13e0ca
      finalcount[i] = (unsigned char)((ctx->count[(i >= 4 ? 0 : 1)]
Packit 13e0ca
                                       >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
Packit 13e0ca
    }
Packit 13e0ca
  sha1_process_bytes ((const uint8_t *)"\200", ctx, 1);
Packit 13e0ca
  while ((ctx->count[0] & 504) != 448)
Packit 13e0ca
    sha1_process_bytes ((const uint8_t *)"\0", ctx, 1);
Packit 13e0ca
  sha1_process_bytes (finalcount, ctx, 8);  /* Should cause a sha1_do_transform() */
Packit 13e0ca
  for (i = 0; i < SHA1_DIGEST_SIZE; i++)
Packit 13e0ca
    {
Packit 13e0ca
      *((uint8_t *)resbuf + i) = (uint8_t)((ctx->state[i>>2]
Packit 13e0ca
                                            >> ((3-(i & 3)) * 8) ) & 255);
Packit 13e0ca
    }
Packit 13e0ca
Packit 13e0ca
  /* Wipe variables */
Packit 13e0ca
  i = 0;
Packit 13e0ca
  XCRYPT_SECURE_MEMSET (ctx, sizeof (struct sha1_ctx));
Packit 13e0ca
  XCRYPT_SECURE_MEMSET (finalcount, 8);  /* SWR */
Packit 13e0ca
Packit 13e0ca
  return resbuf;
Packit 13e0ca
}
Packit 13e0ca
Packit 13e0ca
#endif