raw
experimental-genesis    1 //  /****************************\
experimental-genesis 2 // * EXPERIMENTAL BRANCH. *
experimental-genesis 3 // * FOR LABORATORY USE ONLY. *
experimental-genesis 4 // ********************************
experimental-genesis 5 // ************
experimental-genesis 6 // **************
experimental-genesis 7 // ****************
experimental-genesis 8 // **** **** ****
experimental-genesis 9 // *** *** ***
experimental-genesis 10 // *** *** ***
experimental-genesis 11 // *** * * **
experimental-genesis 12 // ******** ********
experimental-genesis 13 // ******* ******
experimental-genesis 14 // *** **
experimental-genesis 15 // * ******* **
experimental-genesis 16 // ** * * * * *
experimental-genesis 17 // ** * * ***
experimental-genesis 18 // **** * * * * ****
experimental-genesis 19 // **** *** * * ** ***
experimental-genesis 20 // **** ********* ******
experimental-genesis 21 // ******* ***** *******
experimental-genesis 22 // ********* ****** **
experimental-genesis 23 // ** ****** ******
experimental-genesis 24 // ** ******* **
experimental-genesis 25 // ** ******* ***
experimental-genesis 26 // **** ******** ************
experimental-genesis 27 // ************ ************
experimental-genesis 28 // ******** *******
experimental-genesis 29 // ****** ****
experimental-genesis 30 // *** ***
experimental-genesis 31 // ********************************
experimental-genesis 32 // Copyright (c) 2011 The Bitcoin Developers
experimental-genesis 33 // Distributed under the MIT/X11 software license, see the accompanying
experimental-genesis 34 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
experimental-genesis 35
experimental-genesis 36 #include <openssl/aes.h>
experimental-genesis 37 #include <openssl/evp.h>
experimental-genesis 38 #include <vector>
experimental-genesis 39 #include <string>
experimental-genesis 40 #include "headers.h"
experimental-genesis 41 #ifdef WIN32
experimental-genesis 42 #include <windows.h>
experimental-genesis 43 #endif
experimental-genesis 44
experimental-genesis 45 #include "crypter.h"
experimental-genesis 46 #include "main.h"
experimental-genesis 47 #include "util.h"
experimental-genesis 48
experimental-genesis 49 bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
experimental-genesis 50 {
experimental-genesis 51 if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
experimental-genesis 52 return false;
experimental-genesis 53
experimental-genesis 54 // Try to keep the keydata out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap)
experimental-genesis 55 // Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
experimental-genesis 56 // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process.
experimental-genesis 57 mlock(&chKey[0], sizeof chKey);
experimental-genesis 58 mlock(&chIV[0], sizeof chIV);
experimental-genesis 59
experimental-genesis 60 int i = 0;
experimental-genesis 61 if (nDerivationMethod == 0)
experimental-genesis 62 i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
experimental-genesis 63 (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
experimental-genesis 64
experimental-genesis 65 if (i != WALLET_CRYPTO_KEY_SIZE)
experimental-genesis 66 {
experimental-genesis 67 memset(&chKey, 0, sizeof chKey);
experimental-genesis 68 memset(&chIV, 0, sizeof chIV);
experimental-genesis 69 return false;
experimental-genesis 70 }
experimental-genesis 71
experimental-genesis 72 fKeySet = true;
experimental-genesis 73 return true;
experimental-genesis 74 }
experimental-genesis 75
experimental-genesis 76 bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV)
experimental-genesis 77 {
experimental-genesis 78 if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE)
experimental-genesis 79 return false;
experimental-genesis 80
experimental-genesis 81 // Try to keep the keydata out of swap
experimental-genesis 82 // Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
experimental-genesis 83 // Note as well that at no point in this program is any attempt made to prevent stealing of keys by reading the memory of the running process.
experimental-genesis 84 mlock(&chKey[0], sizeof chKey);
experimental-genesis 85 mlock(&chIV[0], sizeof chIV);
experimental-genesis 86
experimental-genesis 87 memcpy(&chKey[0], &chNewKey[0], sizeof chKey);
experimental-genesis 88 memcpy(&chIV[0], &chNewIV[0], sizeof chIV);
experimental-genesis 89
experimental-genesis 90 fKeySet = true;
experimental-genesis 91 return true;
experimental-genesis 92 }
experimental-genesis 93
experimental-genesis 94 bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext)
experimental-genesis 95 {
experimental-genesis 96 if (!fKeySet)
experimental-genesis 97 return false;
experimental-genesis 98
experimental-genesis 99 // max ciphertext len for a n bytes of plaintext is
experimental-genesis 100 // n + AES_BLOCK_SIZE - 1 bytes
experimental-genesis 101 int nLen = vchPlaintext.size();
experimental-genesis 102 int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0;
experimental-genesis 103 vchCiphertext = std::vector<unsigned char> (nCLen);
experimental-genesis 104
experimental-genesis 105 EVP_CIPHER_CTX ctx;
experimental-genesis 106
experimental-genesis 107 EVP_CIPHER_CTX_init(&ctx);
experimental-genesis 108 EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
experimental-genesis 109
experimental-genesis 110 EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
experimental-genesis 111 EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
experimental-genesis 112
experimental-genesis 113 EVP_CIPHER_CTX_cleanup(&ctx);
experimental-genesis 114
experimental-genesis 115 vchCiphertext.resize(nCLen + nFLen);
experimental-genesis 116 return true;
experimental-genesis 117 }
experimental-genesis 118
experimental-genesis 119 bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext)
experimental-genesis 120 {
experimental-genesis 121 if (!fKeySet)
experimental-genesis 122 return false;
experimental-genesis 123
experimental-genesis 124 // plaintext will always be equal to or lesser than length of ciphertext
experimental-genesis 125 int nLen = vchCiphertext.size();
experimental-genesis 126 int nPLen = nLen, nFLen = 0;
experimental-genesis 127
experimental-genesis 128 vchPlaintext = CKeyingMaterial(nPLen);
experimental-genesis 129
experimental-genesis 130 EVP_CIPHER_CTX ctx;
experimental-genesis 131
experimental-genesis 132 EVP_CIPHER_CTX_init(&ctx);
experimental-genesis 133 EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
experimental-genesis 134
experimental-genesis 135 EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
experimental-genesis 136 EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
experimental-genesis 137
experimental-genesis 138 EVP_CIPHER_CTX_cleanup(&ctx);
experimental-genesis 139
experimental-genesis 140 vchPlaintext.resize(nPLen + nFLen);
experimental-genesis 141 return true;
experimental-genesis 142 }
experimental-genesis 143
experimental-genesis 144
experimental-genesis 145 bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
experimental-genesis 146 {
experimental-genesis 147 CCrypter cKeyCrypter;
experimental-genesis 148 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
experimental-genesis 149 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
experimental-genesis 150 if(!cKeyCrypter.SetKey(vMasterKey, chIV))
experimental-genesis 151 return false;
experimental-genesis 152 return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext);
experimental-genesis 153 }
experimental-genesis 154
experimental-genesis 155 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext)
experimental-genesis 156 {
experimental-genesis 157 CCrypter cKeyCrypter;
experimental-genesis 158 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
experimental-genesis 159 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
experimental-genesis 160 if(!cKeyCrypter.SetKey(vMasterKey, chIV))
experimental-genesis 161 return false;
experimental-genesis 162 return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
experimental-genesis 163 }