md5.c - vx32 - Local 9vx git repository for patches.
 (HTM) git clone git://r-36.net/vx32
 (DIR) Log
 (DIR) Files
 (DIR) Refs
       ---
       md5.c (3418B)
       ---
            1 #include "os.h"
            2 #include "libsec.h"
            3 
            4 /*
            5  *  rfc1321 requires that I include this.  The code is new.  The constants
            6  *  all come from the rfc (hence the copyright).  We trade a table for the
            7  *  macros in rfc.  The total size is a lot less. -- presotto
            8  *
            9  *        Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
           10  *        rights reserved.
           11  *
           12  *        License to copy and use this software is granted provided that it
           13  *        is identified as the "RSA Data Security, Inc. MD5 Message-Digest
           14  *        Algorithm" in all material mentioning or referencing this software
           15  *        or this function.
           16  *
           17  *        License is also granted to make and use derivative works provided
           18  *        that such works are identified as "derived from the RSA Data
           19  *        Security, Inc. MD5 Message-Digest Algorithm" in all material
           20  *        mentioning or referencing the derived work.
           21  *
           22  *        RSA Data Security, Inc. makes no representations concerning either
           23  *        the merchantability of this software or the suitability of this
           24  *        software forany particular purpose. It is provided "as is"
           25  *        without express or implied warranty of any kind.
           26  *        These notices must be retained in any copies of any part of this
           27  *        documentation and/or software.
           28  */
           29 
           30 static void encode(uchar*, uint32*, ulong);
           31 
           32 extern void _md5block(uchar*, ulong, uint32*);
           33 
           34 MD5state*
           35 md5(uchar *p, ulong len, uchar *digest, MD5state *s)
           36 {
           37         uint32 x[16];
           38         uchar buf[128];
           39         int i;
           40         uchar *e;
           41 
           42         if(s == nil){
           43                 s = malloc(sizeof(*s));
           44                 if(s == nil)
           45                         return nil;
           46                 memset(s, 0, sizeof(*s));
           47                 s->malloced = 1;
           48         }
           49 
           50         if(s->seeded == 0){
           51                 /* seed the state, these constants would look nicer big-endian */
           52                 s->state[0] = 0x67452301;
           53                 s->state[1] = 0xefcdab89;
           54                 s->state[2] = 0x98badcfe;
           55                 s->state[3] = 0x10325476;
           56                 s->seeded = 1;
           57         }
           58 
           59         /* fill out the partial 64 byte block from previous calls */
           60         if(s->blen){
           61                 i = 64 - s->blen;
           62                 if(len < i)
           63                         i = len;
           64                 memmove(s->buf + s->blen, p, i);
           65                 len -= i;
           66                 s->blen += i;
           67                 p += i;
           68                 if(s->blen == 64){
           69                         _md5block(s->buf, s->blen, s->state);
           70                         s->len += s->blen;
           71                         s->blen = 0;
           72                 }
           73         }
           74 
           75         /* do 64 byte blocks */
           76         i = len & ~0x3f;
           77         if(i){
           78                 _md5block(p, i, s->state);
           79                 s->len += i;
           80                 len -= i;
           81                 p += i;
           82         }
           83 
           84         /* save the left overs if not last call */
           85         if(digest == 0){
           86                 if(len){
           87                         memmove(s->buf, p, len);
           88                         s->blen += len;
           89                 }
           90                 return s;
           91         }
           92 
           93         /*
           94          *  this is the last time through, pad what's left with 0x80,
           95          *  0's, and the input count to create a multiple of 64 bytes
           96          */
           97         if(s->blen){
           98                 p = s->buf;
           99                 len = s->blen;
          100         } else {
          101                 memmove(buf, p, len);
          102                 p = buf;
          103         }
          104         s->len += len;
          105         e = p + len;
          106         if(len < 56)
          107                 i = 56 - len;
          108         else
          109                 i = 120 - len;
          110         memset(e, 0, i);
          111         *e = 0x80;
          112         len += i;
          113 
          114         /* append the count */
          115         x[0] = s->len<<3;
          116         x[1] = s->len>>29;
          117         encode(p+len, x, 8);
          118 
          119         /* digest the last part */
          120         _md5block(p, len+8, s->state);
          121         s->len += len;
          122 
          123         /* return result and free state */
          124         encode(digest, s->state, MD5dlen);
          125         if(s->malloced == 1)
          126                 free(s);
          127         return nil;
          128 }
          129 
          130 /*
          131  *        encodes input (uint32) into output (uchar). Assumes len is
          132  *        a multiple of 4.
          133  */
          134 static void
          135 encode(uchar *output, uint32 *input, ulong len)
          136 {
          137         uint32 x;
          138         uchar *e;
          139 
          140         for(e = output + len; output < e;) {
          141                 x = *input++;
          142                 *output++ = x;
          143                 *output++ = x >> 8;
          144                 *output++ = x >> 16;
          145                 *output++ = x >> 24;
          146         }
          147 }
          148 
          149 DigestState*
          150 hmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest,
          151         DigestState *s)
          152 {
          153         return hmac_x(p, len, key, klen, digest, s, md5, MD5dlen);
          154 }