Back to home page

Bitcoin sources

 
 

    


0001 // Copyright (c) 2011 The Bitcoin Developers
0002 // Distributed under the MIT/X11 software license, see the accompanying
0003 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
0004 #ifndef __CRYPTER_H__
0005 #define __CRYPTER_H__
0006 
0007 #include "key.h"
0008 
0009 const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
0010 const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
0011 
0012 /*
0013 Private key encryption is done based on a CMasterKey,
0014 which holds a salt and random encryption key.
0015 
0016 CMasterKeys are encrypted using AES-256-CBC using a key
0017 derived using derivation method nDerivationMethod
0018 (0 == EVP_sha512()) and derivation iterations nDeriveIterations.
0019 vchOtherDerivationParameters is provided for alternative algorithms
0020 which may require more parameters (such as scrypt).
0021 
0022 Wallet Private Keys are then encrypted using AES-256-CBC
0023 with the double-sha256 of the public key as the IV, and the
0024 master key's key as the encryption key (see keystore.[ch]).
0025 */
0026 
0027 class CMasterKey
0028 {
0029 public:
0030     std::vector<unsigned char> vchCryptedKey;
0031     std::vector<unsigned char> vchSalt;
0032     // 0 = EVP_sha512()
0033     // 1 = scrypt()
0034     unsigned int nDerivationMethod;
0035     unsigned int nDeriveIterations;
0036     // Use this for more parameters to key derivation,
0037     // such as the various parameters to scrypt
0038     std::vector<unsigned char> vchOtherDerivationParameters;
0039 
0040     IMPLEMENT_SERIALIZE
0041     (
0042         READWRITE(vchCryptedKey);
0043         READWRITE(vchSalt);
0044         READWRITE(nDerivationMethod);
0045         READWRITE(nDeriveIterations);
0046         READWRITE(vchOtherDerivationParameters);
0047     )
0048     CMasterKey()
0049     {
0050         // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
0051         // ie slightly lower than the lowest hardware we need bother supporting
0052         nDeriveIterations = 25000;
0053         nDerivationMethod = 0;
0054         vchOtherDerivationParameters = std::vector<unsigned char>(0);
0055     }
0056 };
0057 
0058 typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
0059 
0060 class CCrypter
0061 {
0062 private:
0063     unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
0064     unsigned char chIV[WALLET_CRYPTO_KEY_SIZE];
0065     bool fKeySet;
0066 
0067 public:
0068     bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
0069     bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
0070     bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
0071     bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
0072 
0073     void CleanKey()
0074     {
0075         memset(&chKey, 0, sizeof chKey);
0076         memset(&chIV, 0, sizeof chIV);
0077         munlock(&chKey, sizeof chKey);
0078         munlock(&chIV, sizeof chIV);
0079         fKeySet = false;
0080     }
0081 
0082     CCrypter()
0083     {
0084         fKeySet = false;
0085     }
0086 
0087     ~CCrypter()
0088     {
0089         CleanKey();
0090     }
0091 };
0092 
0093 bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
0094 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char> &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext);
0095 
0096 #endif