| 13 | |
| 14 | namespace wallet { |
| 15 | int CCrypter::BytesToKeySHA512AES(const std::span<const unsigned char> salt, const SecureString& key_data, int count, unsigned char* key, unsigned char* iv) const |
| 16 | { |
| 17 | // This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc |
| 18 | // cipher and sha512 message digest. Because sha512's output size (64b) is |
| 19 | // greater than the aes256 block size (16b) + aes256 key size (32b), |
| 20 | // there's no need to process more than once (D_0). |
| 21 | |
| 22 | if(!count || !key || !iv) |
| 23 | return 0; |
| 24 | |
| 25 | unsigned char buf[CSHA512::OUTPUT_SIZE]; |
| 26 | CSHA512 di; |
| 27 | |
| 28 | di.Write(UCharCast(key_data.data()), key_data.size()); |
| 29 | di.Write(salt.data(), salt.size()); |
| 30 | di.Finalize(buf); |
| 31 | |
| 32 | for(int i = 0; i != count - 1; i++) |
| 33 | di.Reset().Write(buf, sizeof(buf)).Finalize(buf); |
| 34 | |
| 35 | memcpy(key, buf, WALLET_CRYPTO_KEY_SIZE); |
| 36 | memcpy(iv, buf + WALLET_CRYPTO_KEY_SIZE, WALLET_CRYPTO_IV_SIZE); |
| 37 | memory_cleanse(buf, sizeof(buf)); |
| 38 | return WALLET_CRYPTO_KEY_SIZE; |
| 39 | } |
| 40 | |
| 41 | bool CCrypter::SetKeyFromPassphrase(const SecureString& key_data, const std::span<const unsigned char> salt, const unsigned int rounds, const unsigned int derivation_method) |
| 42 | { |