@@ -19,12 +19,14 @@ #include #include #import "OFSHA384Or512Hash.h" +#import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" +#import "OFOutOfRangeException.h" @interface OFSHA384Or512Hash () - (void)of_resetState; @end @@ -57,23 +59,23 @@ 0x431D67C49C100D4C, 0x4CC5D4BECB3E42B6, 0x597F299CFC657E2A, 0x5FCB6FAB3AD6FAEC, 0x6C44198C4A475817 }; static OF_INLINE void -byteSwapVectorIfLE(uint64_t *vector, uint8_t length) +byteSwapVectorIfLE(uint64_t *vector, uint_fast8_t length) { #ifndef OF_BIG_ENDIAN - for (uint8_t i = 0; i < length; i++) + for (uint_fast8_t i = 0; i < length; i++) vector[i] = OF_BSWAP64(vector[i]); #endif } static void processBlock(uint64_t *state, uint64_t *buffer) { uint64_t new[8]; - uint8_t i; + uint_fast8_t i; new[0] = state[0]; new[1] = state[1]; new[2] = state[2]; new[3] = state[3]; @@ -145,10 +147,14 @@ - (instancetype)init { self = [super init]; @try { + _iVarsData = [[OFSecureData alloc] + initWithCount: sizeof(*_iVars)]; + _iVars = [_iVarsData items]; + if ([self class] == [OFSHA384Or512Hash class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } @@ -158,96 +164,104 @@ @throw e; } return self; } + +- (instancetype)of_init +{ + return [super init]; +} - (void)dealloc { - [self reset]; + [_iVarsData release]; [super dealloc]; } - (id)copy { - OFSHA384Or512Hash *copy = [[[self class] alloc] init]; + OFSHA384Or512Hash *copy = [[[self class] alloc] of_init]; - memcpy(copy->_state, _state, sizeof(_state)); - memcpy(copy->_bits, _bits, sizeof(_bits)); - memcpy(©->_buffer, &_buffer, sizeof(_buffer)); - copy->_bufferLength = _bufferLength; + copy->_iVarsData = [_iVarsData copy]; + copy->_iVars = [copy->_iVarsData items]; copy->_calculated = _calculated; return copy; } - (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]; - if (UINT64_MAX - _bits[0] < (length * 8)) - _bits[1]++; - _bits[0] += (length * 8); + if (length > SIZE_MAX / 8) + @throw [OFOutOfRangeException exception]; + + if (UINT64_MAX - _iVars->bits[0] < (length * 8)) + _iVars->bits[1]++; + _iVars->bits[0] += (length * 8); while (length > 0) { - size_t min = 128 - _bufferLength; + size_t min = 128 - _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 == 128) { - processBlock(_state, _buffer.words); - _bufferLength = 0; + if (_iVars->bufferLength == 128) { + 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, 128 - _bufferLength - 1); - - if (_bufferLength >= 112) { - processBlock(_state, _buffer.words); - memset(_buffer.bytes, 0, 128); - } - - _buffer.words[14] = OF_BSWAP64_IF_LE(_bits[1]); - _buffer.words[15] = OF_BSWAP64_IF_LE(_bits[0]); - - processBlock(_state, _buffer.words); - memset(&_buffer, 0, sizeof(_buffer)); - byteSwapVectorIfLE(_state, 8); - _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, + 128 - _iVars->bufferLength - 1); + + if (_iVars->bufferLength >= 112) { + processBlock(_iVars->state, _iVars->buffer.words); + of_explicit_memset(_iVars->buffer.bytes, 0, 128); + } + + _iVars->buffer.words[14] = OF_BSWAP64_IF_LE(_iVars->bits[1]); + _iVars->buffer.words[15] = OF_BSWAP64_IF_LE(_iVars->bits[0]); + + processBlock(_iVars->state, _iVars->buffer.words); + of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer)); + byteSwapVectorIfLE(_iVars->state, 8); + _calculated = true; + + return (const unsigned char *)_iVars->state; } - (void)reset { [self of_resetState]; - memset(_bits, 0, sizeof(_bits)); - memset(&_buffer, 0, sizeof(_buffer)); - _bufferLength = 0; + of_explicit_memset(_iVars->bits, 0, sizeof(_iVars->bits)); + of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer)); + _iVars->bufferLength = 0; _calculated = false; } - (void)of_resetState { OF_UNRECOGNIZED_SELECTOR } @end