@@ -18,12 +18,14 @@ #include "config.h" #include #import "OFRIPEMD160Hash.h" +#import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" +#import "OFOutOfRangeException.h" @interface OFRIPEMD160Hash () - (void)of_resetState; @end @@ -61,23 +63,23 @@ 15, 5, 8, 11, 14, 14, 6, 14, 6, 9, 12, 9, 12, 5, 15, 8, 8, 5, 12, 9, 12, 5, 14, 6, 8, 13, 6, 5, 15, 13, 11, 11 }; static OF_INLINE void -byteSwapVectorIfBE(uint32_t *vector, uint8_t length) +byteSwapVectorIfBE(uint32_t *vector, uint_fast8_t length) { #ifdef OF_BIG_ENDIAN - for (uint8_t i = 0; i < length; i++) + for (uint_fast8_t i = 0; i < length; i++) vector[i] = OF_BSWAP32(vector[i]); #endif } static void processBlock(uint32_t *state, uint32_t *buffer) { uint32_t new[5], new2[5]; - uint8_t i = 0; + uint_fast8_t i = 0; new[0] = new2[0] = state[0]; new[1] = new2[1] = state[1]; new[2] = new2[2] = state[2]; new[3] = new2[3] = state[3]; @@ -151,102 +153,121 @@ - (instancetype)init { self = [super init]; - [self of_resetState]; + @try { + _iVarsData = [[OFSecureData alloc] + initWithCount: sizeof(*_iVars)]; + _iVars = [_iVarsData items]; + + [self of_resetState]; + } @catch (id e) { + [self release]; + @throw e; + } return self; } + +- (instancetype)of_init +{ + return [super init]; +} - (void)dealloc { - [self reset]; + [_iVarsData release]; [super dealloc]; } - (id)copy { - OFRIPEMD160Hash *copy = [[OFRIPEMD160Hash alloc] init]; + OFRIPEMD160Hash *copy = [[OFRIPEMD160Hash alloc] of_init]; - memcpy(copy->_state, _state, sizeof(_state)); - copy->_bits = _bits; - memcpy(©->_buffer, &_buffer, sizeof(_buffer)); - copy->_bufferLength = _bufferLength; + copy->_iVarsData = [_iVarsData copy]; + copy->_iVars = [copy->_iVarsData items]; copy->_calculated = _calculated; return copy; } - (void)of_resetState { - _state[0] = 0x67452301; - _state[1] = 0xEFCDAB89; - _state[2] = 0x98BADCFE; - _state[3] = 0x10325476; - _state[4] = 0xC3D2E1F0; + _iVars->state[0] = 0x67452301; + _iVars->state[1] = 0xEFCDAB89; + _iVars->state[2] = 0x98BADCFE; + _iVars->state[3] = 0x10325476; + _iVars->state[4] = 0xC3D2E1F0; } - (void)updateWithBuffer: (const void *)buffer_ length: (size_t)length { - const uint8_t *buffer = buffer_; + const unsigned char *buffer = buffer_; if (_calculated) @throw [OFHashAlreadyCalculatedException exceptionWithObject: self]; - _bits += (length * 8); + if (length > SIZE_MAX / 8) + @throw [OFOutOfRangeException exception]; + + _iVars->bits += (length * 8); while (length > 0) { - size_t min = 64 - _bufferLength; + size_t min = 64 - _iVars->bufferLength; if (min > length) min = length; - memcpy(_buffer.bytes + _bufferLength, buffer, min); - _bufferLength += min; + memcpy(_iVars->buffer.bytes + _iVars->bufferLength, + buffer, min); + _iVars->bufferLength += min; buffer += min; length -= min; - if (_bufferLength == 64) { - processBlock(_state, _buffer.words); - _bufferLength = 0; + if (_iVars->bufferLength == 64) { + processBlock(_iVars->state, _iVars->buffer.words); + _iVars->bufferLength = 0; } } } - (const unsigned char *)digest { if (_calculated) - return (const uint8_t *)_state; - - _buffer.bytes[_bufferLength] = 0x80; - memset(_buffer.bytes + _bufferLength + 1, 0, 64 - _bufferLength - 1); - - if (_bufferLength >= 56) { - processBlock(_state, _buffer.words); - memset(_buffer.bytes, 0, 64); - } - - _buffer.words[14] = OF_BSWAP32_IF_BE((uint32_t)(_bits & 0xFFFFFFFF)); - _buffer.words[15] = OF_BSWAP32_IF_BE((uint32_t)(_bits >> 32)); - - processBlock(_state, _buffer.words); - memset(&_buffer, 0, sizeof(_buffer)); - byteSwapVectorIfBE(_state, 5); - _calculated = true; - - return (const uint8_t *)_state; + return (const unsigned char *)_iVars->state; + + _iVars->buffer.bytes[_iVars->bufferLength] = 0x80; + of_explicit_memset(_iVars->buffer.bytes + _iVars->bufferLength + 1, 0, + 64 - _iVars->bufferLength - 1); + + if (_iVars->bufferLength >= 56) { + processBlock(_iVars->state, _iVars->buffer.words); + of_explicit_memset(_iVars->buffer.bytes, 0, 64); + } + + _iVars->buffer.words[14] = + OF_BSWAP32_IF_BE((uint32_t)(_iVars->bits & 0xFFFFFFFF)); + _iVars->buffer.words[15] = + OF_BSWAP32_IF_BE((uint32_t)(_iVars->bits >> 32)); + + processBlock(_iVars->state, _iVars->buffer.words); + of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer)); + byteSwapVectorIfBE(_iVars->state, 5); + _calculated = true; + + return (const unsigned char *)_iVars->state; } - (void)reset { [self of_resetState]; - _bits = 0; - memset(&_buffer, 0, sizeof(_buffer)); - _bufferLength = 0; + _iVars->bits = 0; + of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer)); + _iVars->bufferLength = 0; _calculated = false; } @end