Index: src/OFHashes.h ================================================================== --- src/OFHashes.h +++ src/OFHashes.h @@ -16,12 +16,14 @@ @interface OFMD5Hash: OFObject { uint32_t buf[4]; uint32_t bits[2]; uint8_t in[64]; + + BOOL calculated; } - init; - (void)updateWithBuffer: (const uint8_t*)buf ofSize: (size_t)size; - (uint8_t*)digest; @end Index: src/OFHashes.m ================================================================== --- src/OFHashes.m +++ src/OFHashes.m @@ -19,21 +19,25 @@ #ifdef BIG_ENDIAN inline void bswap(uint8_t *buf, size_t len) { uint32_t t; - do { + while (len--) { t = (uint32_t)((uint32_t)buf[3] << 8 | buf[2]) << 16 | ((uint32_t)buf[1] << 8 | buf[0]); *(uint32_t*)buf = t; buf += 4; - } while(--len); + } } #else #define bswap(buf, len) #endif +/******* + * MD5 * + *******/ + /* The four MD5 core functions - F1 is optimized somewhat */ #define F1(x, y, z) (z ^ (x & (y ^ z))) #define F2(x, y, z) F1(z, x, y) #define F3(x, y, z) (x ^ y ^ z) #define F4(x, y, z) (y ^ (x | ~z)) @@ -135,19 +139,26 @@ buf[2] = 0x98BADCFE; buf[3] = 0x10325476; bits[0] = 0; bits[1] = 0; + + calculated = NO; } return self; } - (void)updateWithBuffer: (const uint8_t*)buffer ofSize: (size_t)size { uint32_t t; + + if (calculated) + return; + if (size == 0) + return; /* Update bitcount */ t = bits[0]; if ((bits[0] = t + ((uint32_t)size << 3)) < t) bits[1]++; /* Carry from low to high */ @@ -187,10 +198,13 @@ - (uint8_t*)digest { uint8_t *p; size_t count; + if (calculated) + return (uint8_t*)buf; + /* Compute number of bytes mod 64 */ count = (bits[0] >> 3) & 0x3F; /* * Set the first char of padding to 0x80. This is safe since there is @@ -221,9 +235,11 @@ ((uint32_t*)in)[14] = bits[0]; ((uint32_t*)in)[15] = bits[1]; md5_transform(buf, (uint32_t*)in); bswap((uint8_t*)buf, 4); + + calculated = YES; return (uint8_t*)buf; } @end