diff options
author | Luo Jinghua <sunmoon1997@gmail.com> | 2009-10-27 22:57:30 +0800 |
---|---|---|
committer | Luo Jinghua <sunmoon1997@gmail.com> | 2009-10-27 22:57:30 +0800 |
commit | 667bc4a33b61609e186d70e8b45bdadf6dd16477 (patch) | |
tree | 59805db8c80b2f18e145238f5597ef5fa1c11cac | |
parent | 52bab999c3872347da7aa1f346d7735b87135688 (diff) |
milkway: cleanup code
-rw-r--r-- | milkway/md5.c | 11 | ||||
-rw-r--r-- | milkway/md5.h | 21 | ||||
-rw-r--r-- | milkway/mw-checksum.c | 124 | ||||
-rw-r--r-- | milkway/mw-checksum.h | 29 | ||||
-rw-r--r-- | milkway/sha1.c | 29 |
5 files changed, 172 insertions, 42 deletions
diff --git a/milkway/md5.c b/milkway/md5.c index 970fa54..af93f2b 100644 --- a/milkway/md5.c +++ b/milkway/md5.c @@ -20,6 +20,7 @@ #include "config.h" #endif +#include "milkwayint.h" #include "md5.h" #include <string.h> @@ -27,7 +28,9 @@ typedef mw_uint32_t u32; typedef mw_uint8_t u8; -#ifndef WORDS_BIGENDIAN +static void MD5Transform(u32 buf[4], u32 const in[16]); + +#if 1 //ndef WORDS_BIGENDIAN #define byteReverse(buf, len) /* Nothing */ #else /* @@ -150,7 +153,7 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx) MD5Transform(ctx->buf, (u32 *) ctx->in); byteReverse((unsigned char *) ctx->buf, 4); memcpy(digest, ctx->buf, 16); - memset(ctx, 0, sizeof(ctx)); /* In case it's sensitive */ + memset(ctx, 0, sizeof(*ctx)); /* In case it's sensitive */ } /* The four core functions - F1 is optimized somewhat */ @@ -163,14 +166,14 @@ void MD5Final(unsigned char digest[16], struct MD5Context *ctx) /* This is the central step in the MD5 algorithm. */ #define MD5STEP(f, w, x, y, z, data, s) \ - ( w += f(x, y, z) + data, w = w<<s | w>>(32-s), w += x ) + ( w += f(x, y, z) + data, w = w << s | w >> (32 - s), w += x ) /* * The core of the MD5 algorithm, this alters an existing MD5 hash to * reflect the addition of 16 longwords of new data. MD5Update blocks * the data and converts bytes into longwords for this routine. */ -void MD5Transform(u32 buf[4], u32 const in[16]) +static void MD5Transform(u32 buf[4], u32 const in[16]) { register u32 a, b, c, d; diff --git a/milkway/md5.h b/milkway/md5.h index 12d2e1f..bb62262 100644 --- a/milkway/md5.h +++ b/milkway/md5.h @@ -1,7 +1,23 @@ +/* + * This code implements the MD5 message-digest algorithm. + * The algorithm is due to Ron Rivest. This code was + * written by Colin Plumb in 1993, no copyright is claimed. + * This code is in the public domain; do with it what you wish. + * + * Equivalent code is available from RSA Data Security, Inc. + * This code has been tested against that, and is equivalent, + * except that you don't need to include two pages of legalese + * with every copy. + * + * To compute the message digest of a chunk of bytes, declare an + * MD5Context structure, pass it to MD5Init, call MD5Update as + * needed on buffers full of bytes, and then call MD5Final, which + * will fill a supplied 16-byte array with the digest. + */ #ifndef MW_MD5_H #define MW_MD5_H -#include <milkwayint.h> +#include <milkway/mw-types.h> struct MD5Context { mw_uint32_t buf[4]; @@ -19,7 +35,4 @@ MD5Update(struct MD5Context *context, unsigned char const *buf, mw_private void MD5Final(unsigned char digest[16], struct MD5Context *context); -mw_private void -MD5Transform(mw_uint32_t buf[4], mw_uint32_t const in[16]); - #endif diff --git a/milkway/mw-checksum.c b/milkway/mw-checksum.c index 39d44f6..9c9a78d 100644 --- a/milkway/mw-checksum.c +++ b/milkway/mw-checksum.c @@ -17,36 +17,142 @@ #endif #include "milkwayint.h" -#include "milkway/mw-checksum.h" + +#include "md5.h" +#include "sha1.h" #include <stdlib.h> +#include <string.h> + +struct mw_checksum { + enum mw_checksum_mode mode; + union { + struct MD5Context md5; + SHA_CTX sha1; + } ctx; + mw_bool_t finalized; + mw_uint8_t digest[32]; +}; mw_checksum_t* mw_checksum_new(enum mw_checksum_mode mode) { - return NULL; + mw_checksum_t* self = malloc(sizeof(struct mw_checksum)); + if (!self) + return NULL; + + memset (self, 0, sizeof (*self)); + if (mw_checksum_reset(self, mode)) { + free (self); + return NULL; + } + return self; } void -mw_checksum_destroy(mw_checksum_t *checksum) +mw_checksum_destroy(mw_checksum_t *self) { - free (checksum); + free (self); } int -mw_checksum_update(void *data, size_t length) +mw_checksum_update(mw_checksum_t* self, void *data, size_t length) { - return MW_INVALID; + switch (self->mode) { + case MW_CHECKSUM_MD5: + MD5Update(&self->ctx.md5, data, length); + break; + case MW_CHECKSUM_SHA1: + SHA1Update(&self->ctx.sha1, data, length); + break; + default: + return MW_INVALID; + } + return MW_SUCCESS; } int -mw_checksum_final(void) +mw_checksum_final(mw_checksum_t* self) { + if (self->finalized) + return MW_INVALID; + + switch (self->mode) { + case MW_CHECKSUM_MD5: + MD5Final(&self->digest[0], &self->ctx.md5); + break; + case MW_CHECKSUM_SHA1: + SHA1Final(&self->digest[0], &self->ctx.sha1); + break; + default: + return MW_INVALID; + } + + self->finalized = MW_TRUE; return MW_SUCCESS; } int -mw_checksum_reset(enum mw_checksum_mode mode) +mw_checksum_get_digest(mw_checksum_t* self, + void *digest, + size_t len) +{ + size_t digestlen = mw_checksum_get_digest_length(self); + + if (digestlen > len) + return MW_TOO_SMALL; + + mw_checksum_final(self); + memcpy(digest, self->digest, digestlen); + return digestlen; +} + +int +mw_checksum_get_hex_digest(mw_checksum_t* self, + char *digest, + size_t len) { - return MW_INVALID; + size_t digestlen = mw_checksum_get_digest_length(self); + + if (digestlen * 2 + 1 > len) + return MW_TOO_SMALL; + + mw_checksum_final(self); + mw_hexlify(self->digest, digestlen, digest); + return digestlen * 2 + 1; +} + +int +mw_checksum_get_digest_length(mw_checksum_t* self) +{ + switch (self->mode) { + case MW_CHECKSUM_MD5: + return 16; + case MW_CHECKSUM_SHA1: + return 20; + default: + break; + } + return -1; +} + +int +mw_checksum_reset(mw_checksum_t* self, + enum mw_checksum_mode mode) +{ + switch (mode) { + case MW_CHECKSUM_MD5: + MD5Init(&self->ctx.md5); + break; + case MW_CHECKSUM_SHA1: + SHA1Init(&self->ctx.sha1); + break; + default: + return MW_INVALID; + } + + memset (self->digest, 0, sizeof (self->digest)); + self->mode = mode; + self->finalized = MW_FALSE; + return MW_SUCCESS; } diff --git a/milkway/mw-checksum.h b/milkway/mw-checksum.h index 8dc3625..4f15c6d 100644 --- a/milkway/mw-checksum.h +++ b/milkway/mw-checksum.h @@ -25,19 +25,30 @@ enum mw_checksum_mode { struct mw_checksum; typedef struct mw_checksum mw_checksum_t; -mw_checksum_t* +mw_public mw_checksum_t* mw_checksum_new(enum mw_checksum_mode mode); -void -mw_checksum_destroy(mw_checksum_t *checksum); +mw_public void +mw_checksum_destroy(mw_checksum_t *self); -int -mw_checksum_update(void *data, size_t length); +mw_public int +mw_checksum_update(mw_checksum_t *self, void *data, size_t length); -int -mw_checksum_final(void); +mw_public int +mw_checksum_final(mw_checksum_t *self); -int -mw_checksum_reset(enum mw_checksum_mode mode); +mw_public int +mw_checksum_reset(mw_checksum_t *self, enum mw_checksum_mode mode); + +mw_public int +mw_checksum_get_digest(mw_checksum_t* self, + void *digest, size_t len); + +mw_public int +mw_checksum_get_hex_digest(mw_checksum_t* self, + char *digest, size_t len); + +mw_public int +mw_checksum_get_digest_length(mw_checksum_t* self); #endif diff --git a/milkway/sha1.c b/milkway/sha1.c index 74b1875..15662ac 100644 --- a/milkway/sha1.c +++ b/milkway/sha1.c @@ -27,31 +27,27 @@ #include <string.h> -#ifdef WORD_BIGENDIAN -#define LITTLE_ENDIAN -#endif - #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) /* blk0() and blk() perform the initial expand. */ /* I got the idea of expanding during the round function from SSLeay */ -#ifdef LITTLE_ENDIAN -#define blk0(i) (block->l[i] = (rol(block->l[i],24)&(sha1_quadbyte)0xFF00FF00) \ - |(rol(block->l[i],8)&(sha1_quadbyte)0x00FF00FF)) +#ifndef WORDS_BIGENDIAN +#define blk0(i) (block->l[i] = (rol(block->l[i], 24) & (sha1_quadbyte)0xFF00FF00) | \ + (rol(block->l[i], 8) & (sha1_quadbyte)0x00FF00FF)) #else #define blk0(i) block->l[i] #endif -#define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ - ^block->l[(i+2)&15]^block->l[i&15],1)) +#define blk(i) (block->l[i&15] = rol(block->l[(i + 13) & 15]^block->l[(i + 8) & 15] \ + ^block->l[(i + 2) & 15] ^ block->l[i & 15], 1)) /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ -#define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); -#define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); -#define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); -#define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); +#define R0(v,w,x,y,z,i) z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); w = rol(w, 30); +#define R1(v,w,x,y,z,i) z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v,5); w = rol(w, 30); +#define R2(v,w,x,y,z,i) z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5);w = rol(w, 30); +#define R3(v,w,x,y,z,i) z += (((w | x) & y)|(w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); w = rol(w, 30); +#define R4(v,w,x,y,z,i) z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5);w = rol(w, 30); typedef union _BYTE64QUAD16 { sha1_byte c[64]; @@ -121,7 +117,8 @@ void SHA1Update(SHA_CTX *context, sha1_byte *data, unsigned int len) unsigned int i, j; j = (context->count[0] >> 3) & 63; - if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; + if ((context->count[0] += len << 3) < (len << 3)) + context->count[1]++; context->count[1] += (len >> 29); if ((j + len) > 63) { memcpy(&context->buffer[j], data, (i = 64-j)); @@ -154,7 +151,7 @@ void SHA1Final(sha1_byte digest[SHA1_DIGEST_LENGTH], SHA_CTX *context) SHA1Update(context, finalcount, 8); for (i = 0; i < SHA1_DIGEST_LENGTH; i++) { digest[i] = (sha1_byte) - ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + ((context->state[i >> 2] >> ((3 - (i & 3)) * 8) ) & 255); } /* Wipe variables */ i = j = 0; |