Index: src/OFHMAC.m ================================================================== --- src/OFHMAC.m +++ src/OFHMAC.m @@ -16,10 +16,11 @@ */ #include "config.h" #import "OFHMAC.h" +#import "OFSecureData.h" #import "OFHashAlreadyCalculatedException.h" #import "OFInvalidArgumentException.h" @implementation OFHMAC @@ -57,50 +58,58 @@ - (void)setKey: (const void *)key length: (size_t)length { void *pool = objc_autoreleasePoolPush(); size_t blockSize = [_hashClass blockSize]; - uint8_t outerKeyPad[blockSize], innerKeyPad[blockSize]; + OFSecureData *outerKeyPad = [OFSecureData dataWithCount: blockSize]; + OFSecureData *innerKeyPad = [OFSecureData dataWithCount: blockSize]; + unsigned char *outerKeyPadItems = [outerKeyPad items]; + unsigned char *innerKeyPadItems = [innerKeyPad items]; [_outerHash release]; [_innerHash release]; [_outerHashCopy release]; [_innerHashCopy release]; _outerHash = _innerHash = _outerHashCopy = _innerHashCopy = nil; - if (length > blockSize) { - id hash = [_hashClass cryptoHash]; - - [hash updateWithBuffer: key - length: length]; - - length = [_hashClass digestSize]; - if OF_UNLIKELY (length > blockSize) - length = blockSize; - - memcpy(outerKeyPad, [hash digest], length); - memcpy(innerKeyPad, [hash digest], length); - } else { - memcpy(outerKeyPad, key, length); - memcpy(innerKeyPad, key, length); - } - - memset(outerKeyPad + length, 0, blockSize - length); - memset(innerKeyPad + length, 0, blockSize - length); - - for (size_t i = 0; i < blockSize; i++) { - outerKeyPad[i] ^= 0x5C; - innerKeyPad[i] ^= 0x36; - } - - _outerHash = [[_hashClass cryptoHash] retain]; - _innerHash = [[_hashClass cryptoHash] retain]; - - [_outerHash updateWithBuffer: outerKeyPad - length: blockSize]; - [_innerHash updateWithBuffer: innerKeyPad - length: blockSize]; + @try { + if (length > blockSize) { + id hash = [_hashClass cryptoHash]; + + [hash updateWithBuffer: key + length: length]; + + length = [_hashClass digestSize]; + if OF_UNLIKELY (length > blockSize) + length = blockSize; + + memcpy(outerKeyPadItems, [hash digest], length); + memcpy(innerKeyPadItems, [hash digest], length); + } else { + memcpy(outerKeyPadItems, key, length); + memcpy(innerKeyPadItems, key, length); + } + + memset(outerKeyPadItems + length, 0, blockSize - length); + memset(innerKeyPadItems + length, 0, blockSize - length); + + for (size_t i = 0; i < blockSize; i++) { + outerKeyPadItems[i] ^= 0x5C; + innerKeyPadItems[i] ^= 0x36; + } + + _outerHash = [[_hashClass cryptoHash] retain]; + _innerHash = [[_hashClass cryptoHash] retain]; + + [_outerHash updateWithBuffer: outerKeyPadItems + length: blockSize]; + [_innerHash updateWithBuffer: innerKeyPadItems + length: blockSize]; + } @catch (id e) { + [outerKeyPad zero]; + [innerKeyPad zero]; + } objc_autoreleasePoolPop(pool); _outerHashCopy = [_outerHash copy]; _innerHashCopy = [_innerHash copy];