Home | History | Annotate | Download | only in hashes
      1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
      2  *
      3  * LibTomCrypt is a library that provides various cryptographic
      4  * algorithms in a highly modular and flexible manner.
      5  *
      6  * The library is free for all purposes without any express
      7  * guarantee it works.
      8  *
      9  * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com
     10  */
     11 #include "tomcrypt.h"
     12 
     13 /**
     14   @file sha1.c
     15   SHA1 code by Tom St Denis
     16 */
     17 
     18 
     19 #ifdef SHA1
     20 
     21 const struct ltc_hash_descriptor sha1_desc =
     22 {
     23     "sha1",
     24     2,
     25     20,
     26     64,
     27 
     28     /* OID */
     29    { 1, 3, 14, 3, 2, 26,  },
     30    6,
     31 
     32     &sha1_init,
     33     &sha1_process,
     34     &sha1_done,
     35     &sha1_test,
     36     NULL
     37 };
     38 
     39 #define F0(x,y,z)  (z ^ (x & (y ^ z)))
     40 #define F1(x,y,z)  (x ^ y ^ z)
     41 #define F2(x,y,z)  ((x & y) | (z & (x | y)))
     42 #define F3(x,y,z)  (x ^ y ^ z)
     43 
     44 #ifdef LTC_CLEAN_STACK
     45 static int _sha1_compress(hash_state *md, unsigned char *buf)
     46 #else
     47 static int  sha1_compress(hash_state *md, unsigned char *buf)
     48 #endif
     49 {
     50     ulong32 a,b,c,d,e,W[80],i;
     51 #ifdef LTC_SMALL_CODE
     52     ulong32 t;
     53 #endif
     54 
     55     /* copy the state into 512-bits into W[0..15] */
     56     for (i = 0; i < 16; i++) {
     57         LOAD32H(W[i], buf + (4*i));
     58     }
     59 
     60     /* copy state */
     61     a = md->sha1.state[0];
     62     b = md->sha1.state[1];
     63     c = md->sha1.state[2];
     64     d = md->sha1.state[3];
     65     e = md->sha1.state[4];
     66 
     67     /* expand it */
     68     for (i = 16; i < 80; i++) {
     69         W[i] = ROL(W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16], 1);
     70     }
     71 
     72     /* compress */
     73     /* round one */
     74     #define FF0(a,b,c,d,e,i) e = (ROLc(a, 5) + F0(b,c,d) + e + W[i] + 0x5a827999UL); b = ROLc(b, 30);
     75     #define FF1(a,b,c,d,e,i) e = (ROLc(a, 5) + F1(b,c,d) + e + W[i] + 0x6ed9eba1UL); b = ROLc(b, 30);
     76     #define FF2(a,b,c,d,e,i) e = (ROLc(a, 5) + F2(b,c,d) + e + W[i] + 0x8f1bbcdcUL); b = ROLc(b, 30);
     77     #define FF3(a,b,c,d,e,i) e = (ROLc(a, 5) + F3(b,c,d) + e + W[i] + 0xca62c1d6UL); b = ROLc(b, 30);
     78 
     79 #ifdef LTC_SMALL_CODE
     80 
     81     for (i = 0; i < 20; ) {
     82        FF0(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
     83     }
     84 
     85     for (; i < 40; ) {
     86        FF1(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
     87     }
     88 
     89     for (; i < 60; ) {
     90        FF2(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
     91     }
     92 
     93     for (; i < 80; ) {
     94        FF3(a,b,c,d,e,i++); t = e; e = d; d = c; c = b; b = a; a = t;
     95     }
     96 
     97 #else
     98 
     99     for (i = 0; i < 20; ) {
    100        FF0(a,b,c,d,e,i++);
    101        FF0(e,a,b,c,d,i++);
    102        FF0(d,e,a,b,c,i++);
    103        FF0(c,d,e,a,b,i++);
    104        FF0(b,c,d,e,a,i++);
    105     }
    106 
    107     /* round two */
    108     for (; i < 40; )  {
    109        FF1(a,b,c,d,e,i++);
    110        FF1(e,a,b,c,d,i++);
    111        FF1(d,e,a,b,c,i++);
    112        FF1(c,d,e,a,b,i++);
    113        FF1(b,c,d,e,a,i++);
    114     }
    115 
    116     /* round three */
    117     for (; i < 60; )  {
    118        FF2(a,b,c,d,e,i++);
    119        FF2(e,a,b,c,d,i++);
    120        FF2(d,e,a,b,c,i++);
    121        FF2(c,d,e,a,b,i++);
    122        FF2(b,c,d,e,a,i++);
    123     }
    124 
    125     /* round four */
    126     for (; i < 80; )  {
    127        FF3(a,b,c,d,e,i++);
    128        FF3(e,a,b,c,d,i++);
    129        FF3(d,e,a,b,c,i++);
    130        FF3(c,d,e,a,b,i++);
    131        FF3(b,c,d,e,a,i++);
    132     }
    133 #endif
    134 
    135     #undef FF0
    136     #undef FF1
    137     #undef FF2
    138     #undef FF3
    139 
    140     /* store */
    141     md->sha1.state[0] = md->sha1.state[0] + a;
    142     md->sha1.state[1] = md->sha1.state[1] + b;
    143     md->sha1.state[2] = md->sha1.state[2] + c;
    144     md->sha1.state[3] = md->sha1.state[3] + d;
    145     md->sha1.state[4] = md->sha1.state[4] + e;
    146 
    147     return CRYPT_OK;
    148 }
    149 
    150 #ifdef LTC_CLEAN_STACK
    151 static int sha1_compress(hash_state *md, unsigned char *buf)
    152 {
    153    int err;
    154    err = _sha1_compress(md, buf);
    155    burn_stack(sizeof(ulong32) * 87);
    156    return err;
    157 }
    158 #endif
    159 
    160 /**
    161    Initialize the hash state
    162    @param md   The hash state you wish to initialize
    163    @return CRYPT_OK if successful
    164 */
    165 int sha1_init(hash_state * md)
    166 {
    167    LTC_ARGCHK(md != NULL);
    168    md->sha1.state[0] = 0x67452301UL;
    169    md->sha1.state[1] = 0xefcdab89UL;
    170    md->sha1.state[2] = 0x98badcfeUL;
    171    md->sha1.state[3] = 0x10325476UL;
    172    md->sha1.state[4] = 0xc3d2e1f0UL;
    173    md->sha1.curlen = 0;
    174    md->sha1.length = 0;
    175    return CRYPT_OK;
    176 }
    177 
    178 /**
    179    Process a block of memory though the hash
    180    @param md     The hash state
    181    @param in     The data to hash
    182    @param inlen  The length of the data (octets)
    183    @return CRYPT_OK if successful
    184 */
    185 HASH_PROCESS(sha1_process, sha1_compress, sha1, 64)
    186 
    187 /**
    188    Terminate the hash to get the digest
    189    @param md  The hash state
    190    @param out [out] The destination of the hash (20 bytes)
    191    @return CRYPT_OK if successful
    192 */
    193 int sha1_done(hash_state * md, unsigned char *out)
    194 {
    195     int i;
    196 
    197     LTC_ARGCHK(md  != NULL);
    198     LTC_ARGCHK(out != NULL);
    199 
    200     if (md->sha1.curlen >= sizeof(md->sha1.buf)) {
    201        return CRYPT_INVALID_ARG;
    202     }
    203 
    204     /* increase the length of the message */
    205     md->sha1.length += md->sha1.curlen * 8;
    206 
    207     /* append the '1' bit */
    208     md->sha1.buf[md->sha1.curlen++] = (unsigned char)0x80;
    209 
    210     /* if the length is currently above 56 bytes we append zeros
    211      * then compress.  Then we can fall back to padding zeros and length
    212      * encoding like normal.
    213      */
    214     if (md->sha1.curlen > 56) {
    215         while (md->sha1.curlen < 64) {
    216             md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
    217         }
    218         sha1_compress(md, md->sha1.buf);
    219         md->sha1.curlen = 0;
    220     }
    221 
    222     /* pad upto 56 bytes of zeroes */
    223     while (md->sha1.curlen < 56) {
    224         md->sha1.buf[md->sha1.curlen++] = (unsigned char)0;
    225     }
    226 
    227     /* store length */
    228     STORE64H(md->sha1.length, md->sha1.buf+56);
    229     sha1_compress(md, md->sha1.buf);
    230 
    231     /* copy output */
    232     for (i = 0; i < 5; i++) {
    233         STORE32H(md->sha1.state[i], out+(4*i));
    234     }
    235 #ifdef LTC_CLEAN_STACK
    236     zeromem(md, sizeof(hash_state));
    237 #endif
    238     return CRYPT_OK;
    239 }
    240 
    241 /**
    242   Self-test the hash
    243   @return CRYPT_OK if successful, CRYPT_NOP if self-tests have been disabled
    244 */
    245 int  sha1_test(void)
    246 {
    247  #ifndef LTC_TEST
    248     return CRYPT_NOP;
    249  #else
    250   static const struct {
    251       char *msg;
    252       unsigned char hash[20];
    253   } tests[] = {
    254     { "abc",
    255       { 0xa9, 0x99, 0x3e, 0x36, 0x47, 0x06, 0x81, 0x6a,
    256         0xba, 0x3e, 0x25, 0x71, 0x78, 0x50, 0xc2, 0x6c,
    257         0x9c, 0xd0, 0xd8, 0x9d }
    258     },
    259     { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
    260       { 0x84, 0x98, 0x3E, 0x44, 0x1C, 0x3B, 0xD2, 0x6E,
    261         0xBA, 0xAE, 0x4A, 0xA1, 0xF9, 0x51, 0x29, 0xE5,
    262         0xE5, 0x46, 0x70, 0xF1 }
    263     }
    264   };
    265 
    266   int i;
    267   unsigned char tmp[20];
    268   hash_state md;
    269 
    270   for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0]));  i++) {
    271       sha1_init(&md);
    272       sha1_process(&md, (unsigned char*)tests[i].msg, (unsigned long)strlen(tests[i].msg));
    273       sha1_done(&md, tmp);
    274       if (XMEMCMP(tmp, tests[i].hash, 20) != 0) {
    275          return CRYPT_FAIL_TESTVECTOR;
    276       }
    277   }
    278   return CRYPT_OK;
    279   #endif
    280 }
    281 
    282 #endif
    283 
    284 
    285 
    286 /* $Source: /cvs/libtom/libtomcrypt/src/hashes/sha1.c,v $ */
    287 /* $Revision: 1.8 $ */
    288 /* $Date: 2006/11/01 09:28:17 $ */
    289