aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/wallet/crypter.cpp33
-rw-r--r--src/wallet/crypter.h2
2 files changed, 31 insertions, 4 deletions
diff --git a/src/wallet/crypter.cpp b/src/wallet/crypter.cpp
index 0a19139a31..190f8ecf2a 100644
--- a/src/wallet/crypter.cpp
+++ b/src/wallet/crypter.cpp
@@ -5,6 +5,7 @@
#include "crypter.h"
#include "crypto/aes.h"
+#include "crypto/sha512.h"
#include "script/script.h"
#include "script/standard.h"
#include "util.h"
@@ -12,8 +13,33 @@
#include <string>
#include <vector>
#include <boost/foreach.hpp>
-#include <openssl/aes.h>
-#include <openssl/evp.h>
+
+int CCrypter::BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const
+{
+ // This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc
+ // cipher and sha512 message digest. Because sha512's output size (64b) is
+ // greater than the aes256 block size (16b) + aes256 key size (32b),
+ // there's no need to process more than once (D_0).
+
+ if(!count || !key || !iv)
+ return 0;
+
+ unsigned char buf[CSHA512::OUTPUT_SIZE];
+ CSHA512 di;
+
+ di.Write((const unsigned char*)strKeyData.c_str(), strKeyData.size());
+ if(chSalt.size())
+ di.Write(&chSalt[0], chSalt.size());
+ di.Finalize(buf);
+
+ for(int i = 0; i != count - 1; i++)
+ di.Reset().Write(buf, sizeof(buf)).Finalize(buf);
+
+ memcpy(key, buf, WALLET_CRYPTO_KEY_SIZE);
+ memcpy(iv, buf + WALLET_CRYPTO_KEY_SIZE, WALLET_CRYPTO_IV_SIZE);
+ memory_cleanse(buf, sizeof(buf));
+ return WALLET_CRYPTO_KEY_SIZE;
+}
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
{
@@ -22,8 +48,7 @@ bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::v
int i = 0;
if (nDerivationMethod == 0)
- i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
- (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
+ i = BytesToKeySHA512AES(chSalt, strKeyData, nRounds, chKey, chIV);
if (i != (int)WALLET_CRYPTO_KEY_SIZE)
{
diff --git a/src/wallet/crypter.h b/src/wallet/crypter.h
index 3457d40ffd..16f2ba6220 100644
--- a/src/wallet/crypter.h
+++ b/src/wallet/crypter.h
@@ -75,6 +75,8 @@ private:
unsigned char chIV[WALLET_CRYPTO_IV_SIZE];
bool fKeySet;
+ int BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const;
+
public:
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const;