crypter: add a BytesToKey clone to replace the use of openssl

BytesToKeySHA512AES should be functionally identical to EVP_BytesToKey, but
drops the dependency on openssl.
This commit is contained in:
Cory Fields 2015-03-20 01:24:12 -04:00 committed by Pieter Wuille
parent 9049cde4d9
commit 976f9ec264
2 changed files with 31 additions and 4 deletions

View File

@ -5,6 +5,7 @@
#include "crypter.h" #include "crypter.h"
#include "crypto/aes.h" #include "crypto/aes.h"
#include "crypto/sha512.h"
#include "script/script.h" #include "script/script.h"
#include "script/standard.h" #include "script/standard.h"
#include "util.h" #include "util.h"
@ -12,8 +13,33 @@
#include <string> #include <string>
#include <vector> #include <vector>
#include <boost/foreach.hpp> #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) 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; int i = 0;
if (nDerivationMethod == 0) if (nDerivationMethod == 0)
i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], i = BytesToKeySHA512AES(chSalt, strKeyData, nRounds, chKey, chIV);
(unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
if (i != (int)WALLET_CRYPTO_KEY_SIZE) if (i != (int)WALLET_CRYPTO_KEY_SIZE)
{ {

View File

@ -75,6 +75,8 @@ private:
unsigned char chIV[WALLET_CRYPTO_IV_SIZE]; unsigned char chIV[WALLET_CRYPTO_IV_SIZE];
bool fKeySet; bool fKeySet;
int BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const;
public: public:
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod); 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; bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const;