@@ -1,9 +1,9 @@ /* - * Copyright (c) 2016 - 2019 Jonathan Schleifer + * Copyright (c) 2016 - 2020 Jonathan Schleifer * - * https://heap.zone/git/cryptopassphrase.git + * https://nil.im/git/cryptopassphrase.git * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice is present in all copies. * @@ -56,58 +56,54 @@ - (void)derivePassword { OFSHA256Hash *siteHash = [OFSHA256Hash cryptoHashWithAllowsSwappableMemory: true]; size_t passphraseLength, combinedPassphraseLength; - char *combinedPassphrase; + OFSecureData *combinedPassphrase; + char *combinedPassphraseItems; + unsigned char *outputItems; [siteHash updateWithBuffer: _site.UTF8String length: _site.UTF8StringLength]; - if (_output != NULL) { - of_explicit_memset(_output, 0, _length); - [self freeMemory: _output]; - } - - _output = [self allocMemoryWithSize: _length + 1]; - - passphraseLength = combinedPassphraseLength = strlen(_passphrase); + [_output release]; + _output = nil; + _output = [[OFSecureData alloc] initWithCount: _length + 1 + allowsSwappableMemory: false]; + + passphraseLength = combinedPassphraseLength = _passphrase.count - 1; if (_keyFile != nil) { if (SIZE_MAX - combinedPassphraseLength < _keyFile.count) @throw [OFOutOfRangeException exception]; combinedPassphraseLength += _keyFile.count; } - if ((combinedPassphrase = malloc(combinedPassphraseLength)) == NULL) - @throw [OFOutOfMemoryException - exceptionWithRequestedSize: combinedPassphraseLength]; - @try { - memcpy(combinedPassphrase, _passphrase, passphraseLength); - - if (_keyFile != nil) - memcpy(combinedPassphrase + passphraseLength, - _keyFile.items, _keyFile.count); - - of_scrypt(8, 524288, 2, siteHash.digest, - [siteHash.class digestSize], combinedPassphrase, - combinedPassphraseLength, _output, _length, true); - } @finally { - of_explicit_memset(combinedPassphrase, 0, - combinedPassphraseLength); - free(combinedPassphrase); - } + combinedPassphrase = [OFSecureData + dataWithCount: combinedPassphraseLength + allowsSwappableMemory: false]; + combinedPassphraseItems = combinedPassphrase.mutableItems; + memcpy(combinedPassphraseItems, _passphrase.items, passphraseLength); + + if (_keyFile != nil) + memcpy(combinedPassphraseItems + passphraseLength, + _keyFile.items, _keyFile.count); + + outputItems = _output.mutableItems; + of_scrypt(8, 524288, 2, siteHash.digest, [siteHash.class digestSize], + combinedPassphraseItems, combinedPassphraseLength, outputItems, + _length, true); /* * This has a bias, however, this is what scrypt-genpass does and the * legacy mode wants to be compatible to scrypt-genpass. */ - _output[0] = "abcdefghijklmnopqrstuvwxyz"[_output[0] % 26]; - _output[1] = "0123456789"[_output[1] % 10]; - _output[2] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[_output[2] % 26]; + outputItems[0] = "abcdefghijklmnopqrstuvwxyz"[outputItems[0] % 26]; + outputItems[1] = "0123456789"[outputItems[1] % 10]; + outputItems[2] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[outputItems[2] % 26]; for (size_t i = 3; i < _length; i++) - _output[i] = "abcdefghijklmnopqrstuvwxyz" + outputItems[i] = "abcdefghijklmnopqrstuvwxyz" "ABCDEFGHIJKLMNOPQRSTUVWXYZ" - "0123456789"[_output[i] % (26 + 26 + 10)]; + "0123456789"[outputItems[i] % (26 + 26 + 10)]; } @end