Index: src/OFHash.h ================================================================== --- src/OFHash.h +++ src/OFHash.h @@ -70,6 +70,15 @@ * @brief Returns a boolean whether the hash has already been calculated. * * @return A boolean whether the hash has already been calculated */ - (bool)isCalculated; + +/*! + * @brief Resets all state so that a new hash can be calculated. + * + * @warning This invalidates any pointer previously returned by @ref digest. If + * you are still interested in the previous digest, you need to memcpy + * it yourself before calling @ref reset! + */ +- (void)reset; @end Index: src/OFMD5Hash.h ================================================================== --- src/OFMD5Hash.h +++ src/OFMD5Hash.h @@ -30,6 +30,8 @@ uint32_t words[16]; } _buffer; size_t _bufferLength; bool _calculated; } + +- (void)OF_resetState; @end Index: src/OFMD5Hash.m ================================================================== --- src/OFMD5Hash.m +++ src/OFMD5Hash.m @@ -132,16 +132,21 @@ - init { self = [super init]; + [self OF_resetState]; + + return self; +} + +- (void)OF_resetState +{ _state[0] = 0x67452301; _state[1] = 0xEFCDAB89; _state[2] = 0x98BADCFE; _state[3] = 0x10325476; - - return self; } - (void)updateWithBuffer: (const void*)buffer_ length: (size_t)length { @@ -198,6 +203,15 @@ - (bool)isCalculated { return _calculated; } + +- (void)reset +{ + [self OF_resetState]; + _bits = 0; + memset(&_buffer, 0, sizeof(_buffer)); + _bufferLength = 0; + _calculated = false; +} @end Index: src/OFRIPEMD160Hash.h ================================================================== --- src/OFRIPEMD160Hash.h +++ src/OFRIPEMD160Hash.h @@ -30,6 +30,8 @@ uint32_t words[16]; } _buffer; size_t _bufferLength; bool _calculated; } + +- (void)OF_resetState; @end Index: src/OFRIPEMD160Hash.m ================================================================== --- src/OFRIPEMD160Hash.m +++ src/OFRIPEMD160Hash.m @@ -146,17 +146,22 @@ - init { self = [super init]; + [self OF_resetState]; + + return self; +} + +- (void)OF_resetState +{ _state[0] = 0x67452301; _state[1] = 0xEFCDAB89; _state[2] = 0x98BADCFE; _state[3] = 0x10325476; _state[4] = 0xC3D2E1F0; - - return self; } - (void)updateWithBuffer: (const void*)buffer_ length: (size_t)length { @@ -213,6 +218,15 @@ - (bool)isCalculated { return _calculated; } + +- (void)reset +{ + [self OF_resetState]; + _bits = 0; + memset(&_buffer, 0, sizeof(_buffer)); + _bufferLength = 0; + _calculated = false; +} @end Index: src/OFSHA1Hash.h ================================================================== --- src/OFSHA1Hash.h +++ src/OFSHA1Hash.h @@ -30,6 +30,8 @@ uint32_t words[80]; } _buffer; size_t _bufferLength; bool _calculated; } + +- (void)OF_resetState; @end Index: src/OFSHA1Hash.m ================================================================== --- src/OFSHA1Hash.m +++ src/OFSHA1Hash.m @@ -106,17 +106,22 @@ - init { self = [super init]; + [self OF_resetState]; + + return self; +} + +- (void)OF_resetState +{ _state[0] = 0x67452301; _state[1] = 0xEFCDAB89; _state[2] = 0x98BADCFE; _state[3] = 0x10325476; _state[4] = 0xC3D2E1F0; - - return self; } - (void)updateWithBuffer: (const void*)buffer_ length: (size_t)length { @@ -173,6 +178,15 @@ - (bool)isCalculated { return _calculated; } + +- (void)reset +{ + [self OF_resetState]; + _bits = 0; + memset(&_buffer, 0, sizeof(_buffer)); + _bufferLength = 0; + _calculated = false; +} @end Index: src/OFSHA224Hash.m ================================================================== --- src/OFSHA224Hash.m +++ src/OFSHA224Hash.m @@ -26,17 +26,22 @@ - init { self = [super init]; + [self OF_resetState]; + + return self; +} + +- (void)OF_resetState +{ _state[0] = 0xC1059ED8; _state[1] = 0x367CD507; _state[2] = 0x3070DD17; _state[3] = 0xF70E5939; _state[4] = 0xFFC00B31; _state[5] = 0x68581511; _state[6] = 0x64F98FA7; _state[7] = 0xBEFA4FA4; - - return self; } @end Index: src/OFSHA224Or256Hash.h ================================================================== --- src/OFSHA224Or256Hash.h +++ src/OFSHA224Or256Hash.h @@ -30,6 +30,8 @@ uint32_t words[64]; } _buffer; size_t _bufferLength; bool _calculated; } + +- (void)OF_resetState; @end Index: src/OFSHA224Or256Hash.m ================================================================== --- src/OFSHA224Or256Hash.m +++ src/OFSHA224Or256Hash.m @@ -198,6 +198,20 @@ - (bool)isCalculated { return _calculated; } + +- (void)reset +{ + [self OF_resetState]; + _bits = 0; + memset(&_buffer, 0, sizeof(_buffer)); + _bufferLength = 0; + _calculated = false; +} + +- (void)OF_resetState +{ + OF_UNRECOGNIZED_SELECTOR +} @end Index: src/OFSHA256Hash.m ================================================================== --- src/OFSHA256Hash.m +++ src/OFSHA256Hash.m @@ -26,17 +26,22 @@ - init { self = [super init]; + [self OF_resetState]; + + return self; +} + +- (void)OF_resetState +{ _state[0] = 0x6A09E667; _state[1] = 0xBB67AE85; _state[2] = 0x3C6EF372; _state[3] = 0xA54FF53A; _state[4] = 0x510E527F; _state[5] = 0x9B05688C; _state[6] = 0x1F83D9AB; _state[7] = 0x5BE0CD19; - - return self; } @end Index: src/OFSHA384Hash.m ================================================================== --- src/OFSHA384Hash.m +++ src/OFSHA384Hash.m @@ -26,17 +26,22 @@ - init { self = [super init]; + [self OF_resetState]; + + return self; +} + +- (void)OF_resetState +{ _state[0] = 0xCBBB9D5DC1059ED8; _state[1] = 0x629A292A367CD507; _state[2] = 0x9159015A3070DD17; _state[3] = 0x152FECD8F70E5939; _state[4] = 0x67332667FFC00B31; _state[5] = 0x8EB44A8768581511; _state[6] = 0xDB0C2E0D64F98FA7; _state[7] = 0x47B5481DBEFA4FA4; - - return self; } @end Index: src/OFSHA384Or512Hash.h ================================================================== --- src/OFSHA384Or512Hash.h +++ src/OFSHA384Or512Hash.h @@ -30,6 +30,8 @@ uint64_t words[80]; } _buffer; size_t _bufferLength; bool _calculated; } + +- (void)OF_resetState; @end Index: src/OFSHA384Or512Hash.m ================================================================== --- src/OFSHA384Or512Hash.m +++ src/OFSHA384Or512Hash.m @@ -211,6 +211,20 @@ - (bool)isCalculated { return _calculated; } + +- (void)reset +{ + [self OF_resetState]; + memset(&_bits, 0, sizeof(_bits)); + memset(&_buffer, 0, sizeof(_buffer)); + _bufferLength = 0; + _calculated = false; +} + +- (void)OF_resetState +{ + OF_UNRECOGNIZED_SELECTOR +} @end Index: src/OFSHA512Hash.m ================================================================== --- src/OFSHA512Hash.m +++ src/OFSHA512Hash.m @@ -26,17 +26,22 @@ - init { self = [super init]; + [self OF_resetState]; + + return self; +} + +- (void)OF_resetState +{ _state[0] = 0x6A09E667F3BCC908; _state[1] = 0xBB67AE8584CAA73B; _state[2] = 0x3C6EF372FE94F82B; _state[3] = 0xA54FF53A5F1D36F1; _state[4] = 0x510E527FADE682D1; _state[5] = 0x9B05688C2B3E6C1F; _state[6] = 0x1F83D9ABFB41BD6B; _state[7] = 0x5BE0CD19137E2179; - - return self; } @end Index: utils/ofhash/OFHash.m ================================================================== --- utils/ofhash/OFHash.m +++ utils/ofhash/OFHash.m @@ -45,51 +45,50 @@ [OFApplication programName]]; [OFApplication terminateWithStatus: 1]; } -static Class -hashClassForName(OFString *name) +static id +hashForName(OFString *name) { if ([name isEqual: @"md5"]) - return [OFMD5Hash class]; + return [OFMD5Hash hash]; else if ([name isEqual: @"rmd160"] || [name isEqual: @"ripemd160"]) - return [OFRIPEMD160Hash class]; + return [OFRIPEMD160Hash hash]; else if ([name isEqual: @"sha1"]) - return [OFSHA1Hash class]; + return [OFSHA1Hash hash]; else if ([name isEqual: @"sha224"]) - return [OFSHA224Hash class]; + return [OFSHA224Hash hash]; else if ([name isEqual: @"sha256"]) - return [OFSHA256Hash class]; + return [OFSHA256Hash hash]; else if ([name isEqual: @"sha384"]) - return [OFSHA384Hash class]; + return [OFSHA384Hash hash]; else if ([name isEqual: @"sha512"]) - return [OFSHA512Hash class]; + return [OFSHA512Hash hash]; return nil; } @implementation OFHash - (void)applicationDidFinishLaunching { OFArray *arguments = [OFApplication arguments]; - Class hashClass; + id hash; OFEnumerator *enumerator; OFString *path; int exitStatus = 0; if ([arguments count] < 2) help(); - if ((hashClass = hashClassForName([arguments objectAtIndex: 0])) == Nil) + if ((hash = hashForName([arguments firstObject])) == nil) help(); enumerator = [[arguments objectsInRange: of_range(1, [arguments count] - 1)] objectEnumerator]; while ((path = [enumerator nextObject]) != nil) { void *pool = objc_autoreleasePoolPush(); - id hash = [hashClass hash]; OFStream *file; const uint8_t *digest; size_t i, digestSize; if ([path isEqual: @"-"]) @@ -105,10 +104,12 @@ exitStatus = 1; goto outer_loop_end; } } + + [hash reset]; while (![file isAtEndOfStream]) { uint8_t buffer[1024]; size_t length; @@ -125,14 +126,16 @@ } [hash updateWithBuffer: buffer length: length]; } + [file close]; digest = [hash digest]; - digestSize = [hashClass digestSize]; + digestSize = [[hash class] digestSize]; + for (i = 0; i < digestSize; i++) [of_stdout writeFormat: @"%02x", digest[i]]; [of_stdout writeFormat: @" %@\n", path];