Home | History | Annotate | Download | only in src
      1 /*
      2 SHA-1 in C
      3 By Steve Reid <sreid (at) sea-to-sky.net>
      4 100% Public Domain
      5 
      6 -----------------
      7 Modified 7/98
      8 By James H. Brown <jbrown (at) burgoyne.com>
      9 Still 100% Public Domain
     10 
     11 Corrected a problem which generated improper hash values on 16 bit machines
     12 Routine SHA1Update changed from
     13   void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
     14 len)
     15 to
     16   void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
     17 long len)
     18 
     19 The 'len' parameter was declared an int which works fine on 32 bit machines.
     20 However, on 16 bit machines an int is too small for the shifts being done
     21 against
     22 it.  This caused the hash function to generate incorrect values if len was
     23 greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update().
     24 
     25 Since the file IO in main() reads 16K at a time, any file 8K or larger would
     26 be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million
     27 "a"s).
     28 
     29 I also changed the declaration of variables i & j in SHA1Update to
     30 unsigned long from unsigned int for the same reason.
     31 
     32 These changes should make no difference to any 32 bit implementations since
     33 an
     34 int and a long are the same size in those environments.
     35 
     36 --
     37 I also corrected a few compiler warnings generated by Borland C.
     38 1. Added #include <process.h> for exit() prototype
     39 2. Removed unused variable 'j' in SHA1Final
     40 3. Changed exit(0) to return(0) at end of main.
     41 
     42 ALL changes I made can be located by searching for comments containing 'JHB'
     43 -----------------
     44 Modified 8/98
     45 By Steve Reid <sreid (at) sea-to-sky.net>
     46 Still 100% public domain
     47 
     48 1- Removed #include <process.h> and used return() instead of exit()
     49 2- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall)
     50 3- Changed email address from steve (at) edmweb.com to sreid (at) sea-to-sky.net
     51 
     52 -----------------
     53 Modified 4/01
     54 By Saul Kravitz <Saul.Kravitz (at) celera.com>
     55 Still 100% PD
     56 Modified to run on Compaq Alpha hardware.
     57 
     58 -----------------
     59 Modified 07/2002
     60 By Ralph Giles <giles (at) ghostscript.com>
     61 Still 100% public domain
     62 modified for use with stdint types, autoconf
     63 code cleanup, removed attribution comments
     64 switched SHA1Final() argument order for consistency
     65 use SHA1_ prefix for public api
     66 move public api to sha1.h
     67 */
     68 
     69 /*
     70 Test Vectors (from FIPS PUB 180-1)
     71 "abc"
     72   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
     73 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
     74   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
     75 A million repetitions of "a"
     76   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
     77 */
     78 
     79 #include <stdio.h>
     80 #include <string.h>
     81 #include <stdlib.h>
     82 
     83 #include "sha1.h"
     84 
     85 #if defined(_MSC_VER)
     86 #pragma warning(disable : 4267)
     87 #pragma warning(disable : 4996)
     88 #pragma warning(disable : 4100)
     89 #endif
     90 
     91 void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
     92 
     93 #define rol ROTL32
     94 
     95 /* blk0() and blk() perform the initial expand. */
     96 /* I got the idea of expanding during the round function from SSLeay */
     97 /* FIXME: can we do this in an endian-proof way? */
     98 
     99 #ifdef WORDS_BIGENDIAN
    100 #define blk0(i) block->l[i]
    101 #else
    102 #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) | (rol(block->l[i],8)&0x00FF00FF))
    103 #endif
    104 #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] ^ block->l[(i+2)&15]^block->l[i&15],1))
    105 
    106 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */
    107 #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
    108 #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
    109 #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
    110 #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
    111 #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
    112 
    113 
    114 /* Hash a single 512-bit block. This is the core of the algorithm. */
    115 void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
    116 {
    117     uint32_t a, b, c, d, e;
    118     typedef union {
    119         uint8_t c[64];
    120         uint32_t l[16];
    121     } CHAR64LONG16;
    122     CHAR64LONG16* block;
    123 
    124     block = (CHAR64LONG16*)buffer;
    125 
    126     /* Copy context->state[] to working vars */
    127     a = state[0];
    128     b = state[1];
    129     c = state[2];
    130     d = state[3];
    131     e = state[4];
    132 
    133     /* 4 rounds of 20 operations each. Loop unrolled. */
    134     R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3);
    135     R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7);
    136     R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11);
    137     R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15);
    138     R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19);
    139     R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23);
    140     R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27);
    141     R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31);
    142     R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35);
    143     R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39);
    144     R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43);
    145     R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47);
    146     R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51);
    147     R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55);
    148     R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59);
    149     R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63);
    150     R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67);
    151     R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71);
    152     R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75);
    153     R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79);
    154 
    155     /* Add the working vars back into context.state[] */
    156     state[0] += a;
    157     state[1] += b;
    158     state[2] += c;
    159     state[3] += d;
    160     state[4] += e;
    161 
    162     /* Wipe variables */
    163     a = b = c = d = e = 0;
    164 }
    165 
    166 
    167 /* SHA1Init - Initialize new context */
    168 void SHA1_Init(SHA1_CTX* context)
    169 {
    170     /* SHA1 initialization constants */
    171     context->state[0] = 0x67452301;
    172     context->state[1] = 0xEFCDAB89;
    173     context->state[2] = 0x98BADCFE;
    174     context->state[3] = 0x10325476;
    175     context->state[4] = 0xC3D2E1F0;
    176     context->count[0] = 0;
    177   context->count[1] = 0;
    178 }
    179 
    180 
    181 /* Run your data through this. */
    182 void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
    183 {
    184     size_t i, j;
    185 
    186     j = (context->count[0] >> 3) & 63;
    187     if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++;
    188 
    189     context->count[1] += (len >> 29);
    190 
    191     if ((j + len) > 63)
    192   {
    193         memcpy(&context->buffer[j], data, (i = 64-j));
    194         SHA1_Transform(context->state, context->buffer);
    195 
    196         for ( ; i + 63 < len; i += 64)
    197     {
    198             SHA1_Transform(context->state, data + i);
    199         }
    200 
    201         j = 0;
    202     }
    203     else i = 0;
    204     memcpy(&context->buffer[j], &data[i], len - i);
    205 }
    206 
    207 
    208 /* Add padding and return the message digest. */
    209 void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
    210 {
    211     uint32_t i;
    212     uint8_t  finalcount[8];
    213 
    214     for (i = 0; i < 8; i++) {
    215         finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
    216          >> ((3-(i & 3)) * 8) ) & 255);  /* Endian independent */
    217     }
    218     SHA1_Update(context, (uint8_t *)"\200", 1);
    219     while ((context->count[0] & 504) != 448) {
    220         SHA1_Update(context, (uint8_t *)"\0", 1);
    221     }
    222     SHA1_Update(context, finalcount, 8);  /* Should cause a SHA1_Transform() */
    223     for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
    224         digest[i] = (uint8_t)
    225          ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
    226     }
    227 
    228     /* Wipe variables */
    229     i = 0;
    230     memset(context->buffer, 0, 64);
    231     memset(context->state, 0, 20);
    232     memset(context->count, 0, 8);
    233     memset(finalcount, 0, 8);	/* SWR */
    234 }
    235 
    236 //-----------------------------------------------------------------------------
    237 
    238 void sha1_32a ( const void * key, int len, uint32_t seed, void * out )
    239 {
    240   SHA1_CTX context;
    241 
    242   uint8_t digest[20];
    243 
    244   SHA1_Init(&context);
    245   SHA1_Update(&context, (uint8_t*)key, len);
    246   SHA1_Final(&context, digest);
    247 
    248   memcpy(out,&digest[0],4);
    249 }
    250 
    251 //-----------------------------------------------------------------------------
    252 // self test
    253 
    254 //#define TEST
    255 
    256 #ifdef TEST
    257 
    258 static char *test_data[] = {
    259     "abc",
    260     "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
    261     "A million repetitions of 'a'"};
    262 static char *test_results[] = {
    263     "A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D",
    264     "84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
    265     "34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"};
    266 
    267 
    268 void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output)
    269 {
    270     int i,j;
    271     char *c = output;
    272 
    273     for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
    274         for (j = 0; j < 4; j++) {
    275             sprintf(c,"%02X", digest[i*4+j]);
    276             c += 2;
    277         }
    278         sprintf(c, " ");
    279         c += 1;
    280     }
    281     *(c - 1) = '\0';
    282 }
    283 
    284 int main(int argc, char** argv)
    285 {
    286     int k;
    287     SHA1_CTX context;
    288     uint8_t digest[20];
    289     char output[80];
    290 
    291     fprintf(stdout, "verifying SHA-1 implementation... ");
    292 
    293     for (k = 0; k < 2; k++){
    294         SHA1_Init(&context);
    295         SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k]));
    296         SHA1_Final(&context, digest);
    297   digest_to_hex(digest, output);
    298 
    299         if (strcmp(output, test_results[k])) {
    300             fprintf(stdout, "FAIL\n");
    301             fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[k]);
    302             fprintf(stderr,"\t%s returned\n", output);
    303             fprintf(stderr,"\t%s is correct\n", test_results[k]);
    304             return (1);
    305         }
    306     }
    307     /* million 'a' vector we feed separately */
    308     SHA1_Init(&context);
    309     for (k = 0; k < 1000000; k++)
    310         SHA1_Update(&context, (uint8_t*)"a", 1);
    311     SHA1_Final(&context, digest);
    312     digest_to_hex(digest, output);
    313     if (strcmp(output, test_results[2])) {
    314         fprintf(stdout, "FAIL\n");
    315         fprintf(stderr,"* hash of \"%s\" incorrect:\n", test_data[2]);
    316         fprintf(stderr,"\t%s returned\n", output);
    317         fprintf(stderr,"\t%s is correct\n", test_results[2]);
    318         return (1);
    319     }
    320 
    321     /* success */
    322     fprintf(stdout, "ok\n");
    323     return(0);
    324 }
    325 #endif /* TEST */
    326