@@ -17,10 +17,11 @@ #include "config.h" #import "OFHMAC.h" #import "OFSHA256Hash.h" +#import "OFSecureData.h" #import "OFInvalidArgumentException.h" #import "OFOutOfMemoryException.h" #import "OFOutOfRangeException.h" @@ -139,13 +140,13 @@ } void of_scrypt(size_t blockSize, size_t costFactor, size_t parallelization, const unsigned char *salt, size_t saltLength, const char *password, size_t passwordLength, - unsigned char *key, size_t keyLength) + unsigned char *key, size_t keyLength, bool allowsSwappableMemory) { - uint32_t *tmp = NULL, *buffer = NULL; + OFSecureData *tmp = nil, *buffer = nil; OFHMAC *HMAC = nil; if (blockSize == 0 || costFactor <= 1 || (costFactor & (costFactor - 1)) != 0 || parallelization == 0) @throw [OFInvalidArgumentException exception]; @@ -157,47 +158,47 @@ */ OVERFLOW_CHECK_1 OVERFLOW_CHECK_2 @try { - if (costFactor > SIZE_MAX - 1 || - (costFactor + 1) > SIZE_MAX / 128 || - (costFactor + 1) * 128 > SIZE_MAX / blockSize) - @throw [OFOutOfRangeException exception]; - - if ((tmp = malloc((costFactor + 1) * 128 * blockSize)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: (blockSize + - costFactor) * 128]; - - if (parallelization > SIZE_MAX / 128 || - parallelization * 128 > SIZE_MAX / blockSize) - @throw [OFOutOfRangeException exception]; - - if ((buffer = malloc(parallelization * 128 * - blockSize)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: parallelization * 128 * - blockSize]; - - HMAC = [[OFHMAC alloc] initWithHashClass: [OFSHA256Hash class]]; + uint32_t *tmpItems, *bufferItems; + + if (costFactor > SIZE_MAX - 1 || + (costFactor + 1) > SIZE_MAX / 128) + @throw [OFOutOfRangeException exception]; + + tmp = [[OFSecureData alloc] + initWithItemSize: blockSize + count: (costFactor + 1) * 128 + allowsSwappableMemory: allowsSwappableMemory]; + tmpItems = tmp.mutableItems; + + if (parallelization > SIZE_MAX / 128) + @throw [OFOutOfRangeException exception]; + + buffer = [[OFSecureData alloc] + initWithItemSize: blockSize + count: parallelization * 128 + allowsSwappableMemory: allowsSwappableMemory]; + bufferItems = buffer.mutableItems; + + HMAC = [[OFHMAC alloc] + initWithHashClass: [OFSHA256Hash class] + allowsSwappableMemory: allowsSwappableMemory]; of_pbkdf2(HMAC, 1, salt, saltLength, password, passwordLength, - (unsigned char *)buffer, parallelization * 128 * blockSize); + (unsigned char *)bufferItems, + parallelization * 128 * blockSize, allowsSwappableMemory); for (size_t i = 0; i < parallelization; i++) - of_scrypt_romix(buffer + i * 32 * blockSize, blockSize, - costFactor, tmp); + of_scrypt_romix(bufferItems + i * 32 * blockSize, + blockSize, costFactor, tmpItems); - of_pbkdf2(HMAC, 1, (unsigned char *)buffer, parallelization * - 128 * blockSize, password, passwordLength, key, keyLength); + of_pbkdf2(HMAC, 1, (unsigned char *)bufferItems, + parallelization * 128 * blockSize, password, passwordLength, + key, keyLength, allowsSwappableMemory); } @finally { - of_explicit_memset(tmp, 0, (costFactor + 1) * blockSize * 128); - free(tmp); - - of_explicit_memset(buffer, 0, - parallelization * 128 * blockSize); - free(buffer); - + [tmp release]; + [buffer release]; [HMAC release]; } }