"Fossies" - the Fresh Open Source Software Archive

Member "zsync-0.6.2/libzsync/sha1.c" (16 Sep 2010, 5650 Bytes) of package /linux/privat/old/zsync-0.6.2.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "sha1.c" see the Fossies "Dox" file reference documentation.

    1 /*  $OpenBSD: sha1.c,v 1.19 2004/05/28 15:10:27 millert Exp $   */
    2 
    3 /*
    4  * SHA-1 in C
    5  * By Steve Reid <steve@edmweb.com>
    6  * 100% Public Domain
    7  *
    8  * Test Vectors (from FIPS PUB 180-1)
    9  * "abc"
   10  *   A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
   11  * "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
   12  *   84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
   13  * A million repetitions of "a"
   14  *   34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
   15  */
   16 
   17 #include "zsglobal.h"
   18 
   19 #if defined(LIBC_SCCS) && !defined(lint)
   20 static const char rcsid[] = "$OpenBSD: sha1.c,v 1.19 2004/05/28 15:10:27 millert Exp $";
   21 #endif /* LIBC_SCCS and not lint */
   22 
   23 #include <sys/param.h>
   24 #include <stdint.h>
   25 #include <string.h>
   26 #include "sha1.h"
   27 
   28 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
   29 
   30 /* Map Solaris endian stuff to something useful */
   31 #if defined(_BIG_ENDIAN) && !defined(_BYTE_ORDER)
   32 #define LITTLE_ENDIAN 0
   33 #define BIG_ENDIAN 1
   34 #define BYTE_ORDER 1
   35 #endif
   36 
   37 /*
   38  * blk0() and blk() perform the initial expand.
   39  * I got the idea of expanding during the round function from SSLeay
   40  */
   41 #if BYTE_ORDER == LITTLE_ENDIAN
   42 # define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \
   43     |(rol(block->l[i],8)&0x00FF00FF))
   44 #else
   45 # define blk0(i) block->l[i]
   46 #endif
   47 #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \
   48     ^block->l[(i+2)&15]^block->l[i&15],1))
   49 
   50 /*
   51  * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1
   52  */
   53 #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30);
   54 #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30);
   55 #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30);
   56 #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30);
   57 #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30);
   58 
   59 /*
   60  * Hash a single 512-bit block. This is the core of the algorithm.
   61  */
   62 void
   63 SHA1Transform(uint32_t state[5], const uint8_t buffer[SHA1_BLOCK_LENGTH])
   64 {
   65     uint32_t a, b, c, d, e;
   66     uint8_t workspace[SHA1_BLOCK_LENGTH];
   67     typedef union {
   68         uint8_t c[64];
   69         uint32_t l[16];
   70     } CHAR64LONG16;
   71     CHAR64LONG16 *block = (CHAR64LONG16 *)workspace;
   72 
   73     (void)memcpy(block, buffer, SHA1_BLOCK_LENGTH);
   74 
   75     /* Copy context->state[] to working vars */
   76     a = state[0];
   77     b = state[1];
   78     c = state[2];
   79     d = state[3];
   80     e = state[4];
   81 
   82     /* 4 rounds of 20 operations each. Loop unrolled. */
   83     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);
   84     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);
   85     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);
   86     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);
   87     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);
   88     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);
   89     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);
   90     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);
   91     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);
   92     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);
   93     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);
   94     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);
   95     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);
   96     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);
   97     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);
   98     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);
   99     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);
  100     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);
  101     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);
  102     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);
  103 
  104     /* Add the working vars back into context.state[] */
  105     state[0] += a;
  106     state[1] += b;
  107     state[2] += c;
  108     state[3] += d;
  109     state[4] += e;
  110 
  111     /* Wipe variables */
  112     a = b = c = d = e = 0;
  113 }
  114 
  115 
  116 /*
  117  * SHA1Init - Initialize new context
  118  */
  119 void
  120 SHA1Init(SHA1_CTX *context)
  121 {
  122 
  123     /* SHA1 initialization constants */
  124     context->count = 0;
  125     context->state[0] = 0x67452301;
  126     context->state[1] = 0xEFCDAB89;
  127     context->state[2] = 0x98BADCFE;
  128     context->state[3] = 0x10325476;
  129     context->state[4] = 0xC3D2E1F0;
  130 }
  131 
  132 
  133 /*
  134  * Run your data through this.
  135  */
  136 void
  137 SHA1Update(SHA1_CTX *context, const uint8_t *data, size_t len)
  138 {
  139     size_t i, j;
  140 
  141     j = (size_t)((context->count >> 3) & 63);
  142     context->count += (len << 3);
  143     if ((j + len) > 63) {
  144         (void)memcpy(&context->buffer[j], data, (i = 64-j));
  145         SHA1Transform(context->state, context->buffer);
  146         for ( ; i + 63 < len; i += 64)
  147             SHA1Transform(context->state, (uint8_t *)&data[i]);
  148         j = 0;
  149     } else {
  150         i = 0;
  151     }
  152     (void)memcpy(&context->buffer[j], &data[i], len - i);
  153 }
  154 
  155 
  156 /*
  157  * Add padding and return the message digest.
  158  */
  159 void
  160 SHA1Pad(SHA1_CTX *context)
  161 {
  162     uint8_t finalcount[8];
  163     uint8_t i;
  164 
  165     for (i = 0; i < 8; i++) {
  166         finalcount[i] = (uint8_t)((context->count >>
  167             ((7 - (i & 7)) * 8)) & 255);    /* Endian independent */
  168     }
  169     SHA1Update(context, (uint8_t *)"\200", 1);
  170     while ((context->count & 504) != 448)
  171         SHA1Update(context, (uint8_t *)"\0", 1);
  172     SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */
  173 }
  174 
  175 void
  176 SHA1Final(uint8_t digest[SHA1_DIGEST_LENGTH], SHA1_CTX *context)
  177 {
  178     uint8_t i;
  179 
  180     SHA1Pad(context);
  181     if (digest) {
  182         for (i = 0; i < SHA1_DIGEST_LENGTH; i++) {
  183             digest[i] = (uint8_t)
  184                ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
  185         }
  186         memset(context, 0, sizeof(*context));
  187     }
  188 }