sha1.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       sha1.c (2446B)
       ---
            1 #include "os.h"
            2 #include "libsec.h"
            3 
            4 static void encode(uchar*, uint32*, ulong);
            5 
            6 extern void _sha1block(uchar*, ulong, uint32*);
            7 
            8 /*
            9  *  we require len to be a multiple of 64 for all but
           10  *  the last call.  There must be room in the input buffer
           11  *  to pad.
           12  */
           13 SHA1state*
           14 sha1(uchar *p, ulong len, uchar *digest, SHA1state *s)
           15 {
           16         uchar buf[128];
           17         uint32 x[16];
           18         int i;
           19         uchar *e;
           20 
           21         if(s == nil){
           22                 s = malloc(sizeof(*s));
           23                 if(s == nil)
           24                         return nil;
           25                 memset(s, 0, sizeof(*s));
           26                 s->malloced = 1;
           27         }
           28 
           29         if(s->seeded == 0){
           30                 /* seed the state, these constants would look nicer big-endian */
           31                 s->state[0] = 0x67452301;
           32                 s->state[1] = 0xefcdab89;
           33                 s->state[2] = 0x98badcfe;
           34                 s->state[3] = 0x10325476;
           35                 s->state[4] = 0xc3d2e1f0;
           36                 s->seeded = 1;
           37         }
           38 
           39         /* fill out the partial 64 byte block from previous calls */
           40         if(s->blen){
           41                 i = 64 - s->blen;
           42                 if(len < i)
           43                         i = len;
           44                 memmove(s->buf + s->blen, p, i);
           45                 len -= i;
           46                 s->blen += i;
           47                 p += i;
           48                 if(s->blen == 64){
           49                         _sha1block(s->buf, s->blen, s->state);
           50                         s->len += s->blen;
           51                         s->blen = 0;
           52                 }
           53         }
           54 
           55         /* do 64 byte blocks */
           56         i = len & ~0x3f;
           57         if(i){
           58                 _sha1block(p, i, s->state);
           59                 s->len += i;
           60                 len -= i;
           61                 p += i;
           62         }
           63 
           64         /* save the left overs if not last call */
           65         if(digest == 0){
           66                 if(len){
           67                         memmove(s->buf, p, len);
           68                         s->blen += len;
           69                 }
           70                 return s;
           71         }
           72 
           73         /*
           74          *  this is the last time through, pad what's left with 0x80,
           75          *  0's, and the input count to create a multiple of 64 bytes
           76          */
           77         if(s->blen){
           78                 p = s->buf;
           79                 len = s->blen;
           80         } else {
           81                 memmove(buf, p, len);
           82                 p = buf;
           83         }
           84         s->len += len;
           85         e = p + len;
           86         if(len < 56)
           87                 i = 56 - len;
           88         else
           89                 i = 120 - len;
           90         memset(e, 0, i);
           91         *e = 0x80;
           92         len += i;
           93 
           94         /* append the count */
           95         x[0] = s->len>>29;
           96         x[1] = s->len<<3;
           97         encode(p+len, x, 8);
           98 
           99         /* digest the last part */
          100         _sha1block(p, len+8, s->state);
          101         s->len += len+8;
          102 
          103         /* return result and free state */
          104         encode(digest, s->state, SHA1dlen);
          105         if(s->malloced == 1)
          106                 free(s);
          107         return nil;
          108 }
          109 
          110 /*
          111  *        encodes input (ulong) into output (uchar). Assumes len is
          112  *        a multiple of 4.
          113  */
          114 static void
          115 encode(uchar *output, uint32 *input, ulong len)
          116 {
          117         uint32 x;
          118         uchar *e;
          119 
          120         for(e = output + len; output < e;) {
          121                 x = *input++;
          122                 *output++ = x >> 24;
          123                 *output++ = x >> 16;
          124                 *output++ = x >> 8;
          125                 *output++ = x;
          126         }
          127 }
          128 
          129 DigestState*
          130 hmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
          131         DigestState *s)
          132 {
          133         return hmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen);
          134 }