From db6608bd819d10cc2ddb57d18054d62d4ca15596 Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 23 Nov 2003 18:21:42 +0000 Subject: add libsec --- src/libsec/port/md5.c | 148 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 148 insertions(+) create mode 100644 src/libsec/port/md5.c (limited to 'src/libsec/port/md5.c') diff --git a/src/libsec/port/md5.c b/src/libsec/port/md5.c new file mode 100644 index 00000000..bb2f3cb3 --- /dev/null +++ b/src/libsec/port/md5.c @@ -0,0 +1,148 @@ +#include "os.h" +#include + +/* + * rfc1321 requires that I include this. The code is new. The constants + * all come from the rfc (hence the copyright). We trade a table for the + * macros in rfc. The total size is a lot less. -- presotto + * + * Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All + * rights reserved. + * + * License to copy and use this software is granted provided that it + * is identified as the "RSA Data Security, Inc. MD5 Message-Digest + * Algorithm" in all material mentioning or referencing this software + * or this function. + * + * License is also granted to make and use derivative works provided + * that such works are identified as "derived from the RSA Data + * Security, Inc. MD5 Message-Digest Algorithm" in all material + * mentioning or referencing the derived work. + * + * RSA Data Security, Inc. makes no representations concerning either + * the merchantability of this software or the suitability of this + * software forany particular purpose. It is provided "as is" + * without express or implied warranty of any kind. + * These notices must be retained in any copies of any part of this + * documentation and/or software. + */ + +static void encode(uchar*, u32int*, ulong); +static void decode(u32int*, uchar*, ulong); + +extern void _md5block(uchar*, ulong, u32int*); + +MD5state* +md5(uchar *p, ulong len, uchar *digest, MD5state *s) +{ + u32int x[16]; + uchar buf[128]; + int i; + uchar *e; + + if(s == nil){ + s = malloc(sizeof(*s)); + if(s == nil) + return nil; + memset(s, 0, sizeof(*s)); + s->malloced = 1; + } + + if(s->seeded == 0){ + /* seed the state, these constants would look nicer big-endian */ + s->state[0] = 0x67452301; + s->state[1] = 0xefcdab89; + s->state[2] = 0x98badcfe; + s->state[3] = 0x10325476; + s->seeded = 1; + } + + /* fill out the partial 64 byte block from previous calls */ + if(s->blen){ + i = 64 - s->blen; + if(len < i) + i = len; + memmove(s->buf + s->blen, p, i); + len -= i; + s->blen += i; + p += i; + if(s->blen == 64){ + _md5block(s->buf, s->blen, s->state); + s->len += s->blen; + s->blen = 0; + } + } + + /* do 64 byte blocks */ + i = len & ~0x3f; + if(i){ + _md5block(p, i, s->state); + s->len += i; + len -= i; + p += i; + } + + /* save the left overs if not last call */ + if(digest == 0){ + if(len){ + memmove(s->buf, p, len); + s->blen += len; + } + return s; + } + + /* + * this is the last time through, pad what's left with 0x80, + * 0's, and the input count to create a multiple of 64 bytes + */ + if(s->blen){ + p = s->buf; + len = s->blen; + } else { + memmove(buf, p, len); + p = buf; + } + s->len += len; + e = p + len; + if(len < 56) + i = 56 - len; + else + i = 120 - len; + memset(e, 0, i); + *e = 0x80; + len += i; + + /* append the count */ + x[0] = s->len<<3; + x[1] = s->len>>29; + encode(p+len, x, 8); + + /* digest the last part */ + _md5block(p, len+8, s->state); + s->len += len; + + /* return result and free state */ + encode(digest, s->state, MD5dlen); + if(s->malloced == 1) + free(s); + return nil; +} + +/* + * encodes input (u32int) into output (uchar). Assumes len is + * a multiple of 4. + */ +static void +encode(uchar *output, u32int *input, ulong len) +{ + u32int x; + uchar *e; + + for(e = output + len; output < e;) { + x = *input++; + *output++ = x; + *output++ = x >> 8; + *output++ = x >> 16; + *output++ = x >> 24; + } +} -- cgit v1.2.3