Index: src/OFMD5Hash.h ================================================================== --- src/OFMD5Hash.h +++ src/OFMD5Hash.h @@ -17,24 +17,29 @@ #import "OFCryptoHash.h" OF_ASSUME_NONNULL_BEGIN +@class OFSecureData; + /*! * @class OFMD5Hash OFMD5Hash.h ObjFW/OFMD5Hash.h * * @brief A class which provides methods to create an MD5 hash. */ @interface OFMD5Hash: OFObject { - uint32_t _state[4]; - uint64_t _bits; - union of_md5_hash_buffer { - uint8_t bytes[64]; - uint32_t words[16]; - } _buffer; - size_t _bufferLength; + OFSecureData *_iVarsData; + struct of_md5_hash_ivars { + uint32_t state[4]; + uint64_t bits; + union of_md5_hash_buffer { + uint8_t bytes[64]; + uint32_t words[16]; + } buffer; + size_t bufferLength; + } *_iVars; bool _calculated; } @end OF_ASSUME_NONNULL_END Index: src/OFMD5Hash.m ================================================================== --- src/OFMD5Hash.m +++ src/OFMD5Hash.m @@ -18,12 +18,14 @@ #include "config.h" #include #import "OFMD5Hash.h" +#import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" +#import "OFOutOfRangeException.h" @interface OFMD5Hash () - (void)of_resetState; @end @@ -65,23 +67,23 @@ 4, 11, 16, 23, 6, 10, 15, 21 }; 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[4]; - uint8_t i = 0; + uint_fast8_t i = 0; new[0] = state[0]; new[1] = state[1]; new[2] = state[2]; new[3] = state[3]; @@ -137,101 +139,120 @@ - (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 { - OFMD5Hash *copy = [[OFMD5Hash alloc] init]; + OFMD5Hash *copy = [[OFMD5Hash 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; + _iVars->state[0] = 0x67452301; + _iVars->state[1] = 0xEFCDAB89; + _iVars->state[2] = 0x98BADCFE; + _iVars->state[3] = 0x10325476; } - (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, 4); - _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, 4); + _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 Index: src/OFRIPEMD160Hash.h ================================================================== --- src/OFRIPEMD160Hash.h +++ src/OFRIPEMD160Hash.h @@ -17,24 +17,29 @@ #import "OFCryptoHash.h" OF_ASSUME_NONNULL_BEGIN +@class OFSecureData; + /*! * @class OFRIPEMD160Hash OFRIPEMD160Hash.h ObjFW/OFRIPEMD160Hash.h * * @brief A class which provides methods to create a RIPEMD-160 hash. */ @interface OFRIPEMD160Hash: OFObject { - uint32_t _state[5]; - uint64_t _bits; - union of_ripemd_160_hash_buffer { - uint8_t bytes[64]; - uint32_t words[16]; - } _buffer; - size_t _bufferLength; + OFSecureData *_iVarsData; + struct of_ripemd160_hash_ivars { + uint32_t state[5]; + uint64_t bits; + union of_ripemd160_hash_buffer { + uint8_t bytes[64]; + uint32_t words[16]; + } buffer; + size_t bufferLength; + } *_iVars; bool _calculated; } @end OF_ASSUME_NONNULL_END Index: src/OFRIPEMD160Hash.m ================================================================== --- src/OFRIPEMD160Hash.m +++ src/OFRIPEMD160Hash.m @@ -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 Index: src/OFSHA1Hash.h ================================================================== --- src/OFSHA1Hash.h +++ src/OFSHA1Hash.h @@ -17,24 +17,29 @@ #import "OFCryptoHash.h" OF_ASSUME_NONNULL_BEGIN +@class OFSecureData; + /*! * @class OFSHA1Hash OFSHA1Hash.h ObjFW/OFSHA1Hash.h * * @brief A class which provides methods to create an SHA-1 hash. */ @interface OFSHA1Hash: OFObject { - uint32_t _state[5]; - uint64_t _bits; - union of_sha_1_hash_buffer { - uint8_t bytes[64]; - uint32_t words[80]; - } _buffer; - size_t _bufferLength; + OFSecureData *_iVarsData; + struct of_sha1_hash_ivars { + uint32_t state[5]; + uint64_t bits; + union of_sha1_hash_buffer { + uint8_t bytes[64]; + uint32_t words[80]; + } buffer; + size_t bufferLength; + } *_iVars; bool _calculated; } @end OF_ASSUME_NONNULL_END Index: src/OFSHA1Hash.m ================================================================== --- src/OFSHA1Hash.m +++ src/OFSHA1Hash.m @@ -18,12 +18,14 @@ #include "config.h" #include #import "OFSHA1Hash.h" +#import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" +#import "OFOutOfRangeException.h" @interface OFSHA1Hash () - (void)of_resetState; @end @@ -31,23 +33,23 @@ #define G(a, b, c, d) ((b) ^ (c) ^ (d)) #define H(a, b, c, d) (((b) & (c)) | ((d) & ((b) | (c)))) #define I(a, b, c, d) ((b) ^ (c) ^ (d)) static OF_INLINE void -byteSwapVectorIfLE(uint32_t *vector, uint8_t length) +byteSwapVectorIfLE(uint32_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_BSWAP32(vector[i]); #endif } static void processBlock(uint32_t *state, uint32_t *buffer) { uint32_t new[5]; - uint8_t i; + uint_fast8_t i; new[0] = state[0]; new[1] = state[1]; new[2] = state[2]; new[3] = state[3]; @@ -111,102 +113,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 { - OFSHA1Hash *copy = [[OFSHA1Hash alloc] init]; + OFSHA1Hash *copy = [[OFSHA1Hash 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_LE((uint32_t)(_bits >> 32)); - _buffer.words[15] = OF_BSWAP32_IF_LE((uint32_t)(_bits & 0xFFFFFFFF)); - - processBlock(_state, _buffer.words); - memset(&_buffer, 0, sizeof(_buffer)); - byteSwapVectorIfLE(_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_LE((uint32_t)(_iVars->bits >> 32)); + _iVars->buffer.words[15] = + OF_BSWAP32_IF_LE((uint32_t)(_iVars->bits & 0xFFFFFFFF)); + + processBlock(_iVars->state, _iVars->buffer.words); + of_explicit_memset(&_iVars->buffer, 0, sizeof(_iVars->buffer)); + byteSwapVectorIfLE(_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 Index: src/OFSHA224Hash.m ================================================================== --- src/OFSHA224Hash.m +++ src/OFSHA224Hash.m @@ -25,15 +25,15 @@ return 28; } - (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; + _iVars->state[0] = 0xC1059ED8; + _iVars->state[1] = 0x367CD507; + _iVars->state[2] = 0x3070DD17; + _iVars->state[3] = 0xF70E5939; + _iVars->state[4] = 0xFFC00B31; + _iVars->state[5] = 0x68581511; + _iVars->state[6] = 0x64F98FA7; + _iVars->state[7] = 0xBEFA4FA4; } @end Index: src/OFSHA224Or256Hash.h ================================================================== --- src/OFSHA224Or256Hash.h +++ src/OFSHA224Or256Hash.h @@ -17,24 +17,29 @@ #import "OFCryptoHash.h" OF_ASSUME_NONNULL_BEGIN +@class OFSecureData; + /*! * @class OFSHA224Or256Hash OFSHA224Or256Hash.h ObjFW/OFSHA224Or256Hash.h * * @brief A base class for SHA-224 and SHA-256. */ @interface OFSHA224Or256Hash: OFObject { - uint32_t _state[8]; - uint64_t _bits; - union of_sha_224_or_256_hash_buffer { - uint8_t bytes[64]; - uint32_t words[64]; - } _buffer; - size_t _bufferLength; + OFSecureData *_iVarsData; + struct of_sha224_or_256_hash_ivars { + uint32_t state[8]; + uint64_t bits; + union of_sha224_or_256_hash_buffer { + uint8_t bytes[64]; + uint32_t words[64]; + } buffer; + size_t bufferLength; + } *_iVars; bool _calculated; } @end OF_ASSUME_NONNULL_END Index: src/OFSHA224Or256Hash.m ================================================================== --- src/OFSHA224Or256Hash.m +++ src/OFSHA224Or256Hash.m @@ -19,12 +19,14 @@ #include #include #import "OFSHA224Or256Hash.h" +#import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" +#import "OFOutOfRangeException.h" @interface OFSHA224Or256Hash () - (void)of_resetState; @end @@ -46,23 +48,23 @@ 0x748F82EE, 0x78A5636F, 0x84C87814, 0x8CC70208, 0x90BEFFFA, 0xA4506CEB, 0xBEF9A3F7, 0xC67178F2 }; static OF_INLINE void -byteSwapVectorIfLE(uint32_t *vector, uint8_t length) +byteSwapVectorIfLE(uint32_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_BSWAP32(vector[i]); #endif } static void processBlock(uint32_t *state, uint32_t *buffer) { uint32_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]; @@ -134,10 +136,14 @@ - (instancetype)init { self = [super init]; @try { + _iVarsData = [[OFSecureData alloc] + initWithCount: sizeof(*_iVars)]; + _iVars = [_iVarsData items]; + if ([self class] == [OFSHA224Or256Hash class]) { [self doesNotRecognizeSelector: _cmd]; abort(); } @@ -147,94 +153,104 @@ @throw e; } return self; } + +- (instancetype)of_init +{ + return [super init]; +} - (void)dealloc { - [self reset]; + [_iVarsData release]; [super dealloc]; } - (id)copy { - OFSHA224Or256Hash *copy = [[[self class] alloc] init]; + OFSHA224Or256Hash *copy = [[[self class] 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)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_LE((uint32_t)(_bits >> 32)); - _buffer.words[15] = OF_BSWAP32_IF_LE((uint32_t)(_bits & 0xFFFFFFFF)); - - 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, + 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_LE((uint32_t)(_iVars->bits >> 32)); + _iVars->buffer.words[15] = + OF_BSWAP32_IF_LE((uint32_t)(_iVars->bits & 0xFFFFFFFF)); + + 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]; - _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; } - (void)of_resetState { OF_UNRECOGNIZED_SELECTOR } @end Index: src/OFSHA256Hash.m ================================================================== --- src/OFSHA256Hash.m +++ src/OFSHA256Hash.m @@ -25,15 +25,15 @@ return 32; } - (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; + _iVars->state[0] = 0x6A09E667; + _iVars->state[1] = 0xBB67AE85; + _iVars->state[2] = 0x3C6EF372; + _iVars->state[3] = 0xA54FF53A; + _iVars->state[4] = 0x510E527F; + _iVars->state[5] = 0x9B05688C; + _iVars->state[6] = 0x1F83D9AB; + _iVars->state[7] = 0x5BE0CD19; } @end Index: src/OFSHA384Hash.m ================================================================== --- src/OFSHA384Hash.m +++ src/OFSHA384Hash.m @@ -25,15 +25,15 @@ return 48; } - (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; + _iVars->state[0] = 0xCBBB9D5DC1059ED8; + _iVars->state[1] = 0x629A292A367CD507; + _iVars->state[2] = 0x9159015A3070DD17; + _iVars->state[3] = 0x152FECD8F70E5939; + _iVars->state[4] = 0x67332667FFC00B31; + _iVars->state[5] = 0x8EB44A8768581511; + _iVars->state[6] = 0xDB0C2E0D64F98FA7; + _iVars->state[7] = 0x47B5481DBEFA4FA4; } @end Index: src/OFSHA384Or512Hash.h ================================================================== --- src/OFSHA384Or512Hash.h +++ src/OFSHA384Or512Hash.h @@ -17,24 +17,29 @@ #import "OFCryptoHash.h" OF_ASSUME_NONNULL_BEGIN +@class OFSecureData; + /*! * @class OFSHA384Or512Hash OFSHA384Or512Hash.h ObjFW/OFSHA384Or512Hash.h * * @brief A base class for SHA-384 and SHA-512. */ @interface OFSHA384Or512Hash: OFObject { - uint64_t _state[8]; - uint64_t _bits[2]; - union of_sha_384_or_512_hash_buffer { - uint8_t bytes[128]; - uint64_t words[80]; - } _buffer; - size_t _bufferLength; + OFSecureData *_iVarsData; + struct of_sha384_or_512_hash_ivars { + uint64_t state[8]; + uint64_t bits[2]; + union of_sha384_or_512_hash_buffer { + uint8_t bytes[128]; + uint64_t words[80]; + } buffer; + size_t bufferLength; + } *_iVars; bool _calculated; } @end OF_ASSUME_NONNULL_END Index: src/OFSHA384Or512Hash.m ================================================================== --- src/OFSHA384Or512Hash.m +++ src/OFSHA384Or512Hash.m @@ -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 Index: src/OFSHA512Hash.m ================================================================== --- src/OFSHA512Hash.m +++ src/OFSHA512Hash.m @@ -25,15 +25,15 @@ return 64; } - (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; + _iVars->state[0] = 0x6A09E667F3BCC908; + _iVars->state[1] = 0xBB67AE8584CAA73B; + _iVars->state[2] = 0x3C6EF372FE94F82B; + _iVars->state[3] = 0xA54FF53A5F1D36F1; + _iVars->state[4] = 0x510E527FADE682D1; + _iVars->state[5] = 0x9B05688C2B3E6C1F; + _iVars->state[6] = 0x1F83D9ABFB41BD6B; + _iVars->state[7] = 0x5BE0CD19137E2179; } @end Index: src/OFSecureData.m ================================================================== --- src/OFSecureData.m +++ src/OFSecureData.m @@ -81,22 +81,24 @@ count: (size_t)count { self = [super init]; @try { - size_t size, pageSize; + size_t size; +#if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) + size_t pageSize; +#endif if OF_UNLIKELY (itemSize == 0) @throw [OFInvalidArgumentException exception]; if OF_UNLIKELY (count > SIZE_MAX / itemSize) @throw [OFOutOfRangeException exception]; size = itemSize * count; - pageSize = [OFSystemInfo pageSize]; - #if defined(HAVE_MMAP) && defined(HAVE_MLOCK) && defined(MAP_ANON) + pageSize = [OFSystemInfo pageSize]; _mappingSize = OF_ROUND_UP_POW2(pageSize, size); if OF_UNLIKELY (_mappingSize < size) @throw [OFOutOfRangeException exception]; @@ -107,22 +109,20 @@ exceptionWithRequestedSize: _mappingSize]; if OF_UNLIKELY (mlock(_items, _mappingSize) != 0) @throw [OFOutOfMemoryException exceptionWithRequestedSize: _mappingSize]; - - of_explicit_memset(_items, 0, _mappingSize); #else if OF_UNLIKELY ((_items = malloc(size)) == NULL) @throw [OFOutOfMemoryException exceptionWithRequestedSize: size]; - - of_explicit_memset(_items, 0, size); #endif _itemSize = itemSize; _count = count; + + [self zero]; } @catch (id e) { [self release]; @throw e; }