File indexing completed on 2020-06-25 15:44:07
0001
0002
0003
0004
0005 #include <openssl/aes.h>
0006 #include <openssl/evp.h>
0007 #include <vector>
0008 #include <string>
0009 #include "headers.h"
0010
0011 #include "crypter.h"
0012 #include "main.h"
0013 #include "util.h"
0014
0015 bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
0016 {
0017 if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
0018 return false;
0019
0020
0021
0022
0023 mlock(&chKey[0], sizeof chKey);
0024 mlock(&chIV[0], sizeof chIV);
0025
0026 int i = 0;
0027 if (nDerivationMethod == 0)
0028 i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
0029 (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
0030
0031 if (i != WALLET_CRYPTO_KEY_SIZE)
0032 {
0033 memset(&chKey, 0, sizeof chKey);
0034 memset(&chIV, 0, sizeof chIV);
0035 return false;
0036 }
0037
0038 fKeySet = true;
0039 return true;
0040 }
0041
0042 bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV)
0043 {
0044 if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE)
0045 return false;
0046
0047
0048
0049
0050 mlock(&chKey[0], sizeof chKey);
0051 mlock(&chIV[0], sizeof chIV);
0052
0053 memcpy(&chKey[0], &chNewKey[0], sizeof chKey);
0054 memcpy(&chIV[0], &chNewIV[0], sizeof chIV);
0055
0056 fKeySet = true;
0057 return true;
0058 }
0059
0060 bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext)
0061 {
0062 if (!fKeySet)
0063 return false;
0064
0065
0066
0067 int nLen = vchPlaintext.size();
0068 int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0;
0069 vchCiphertext = std::vector<unsigned char> (nCLen);
0070
0071 EVP_CIPHER_CTX ctx;
0072
0073 EVP_CIPHER_CTX_init(&ctx);
0074 EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
0075
0076 EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen);
0077 EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen);
0078
0079 EVP_CIPHER_CTX_cleanup(&ctx);
0080
0081 vchCiphertext.resize(nCLen + nFLen);
0082 return true;
0083 }
0084
0085 bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext)
0086 {
0087 if (!fKeySet)
0088 return false;
0089
0090
0091 int nLen = vchCiphertext.size();
0092 int nPLen = nLen, nFLen = 0;
0093
0094 vchPlaintext = CKeyingMaterial(nPLen);
0095
0096 EVP_CIPHER_CTX ctx;
0097
0098 EVP_CIPHER_CTX_init(&ctx);
0099 EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV);
0100
0101 EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen);
0102 EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen);
0103
0104 EVP_CIPHER_CTX_cleanup(&ctx);
0105
0106 vchPlaintext.resize(nPLen + nFLen);
0107 return true;
0108 }
0109
0110
0111 bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
0112 {
0113 CCrypter cKeyCrypter;
0114 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
0115 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
0116 if(!cKeyCrypter.SetKey(vMasterKey, chIV))
0117 return false;
0118 return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext);
0119 }
0120
0121 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext)
0122 {
0123 CCrypter cKeyCrypter;
0124 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
0125 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
0126 if(!cKeyCrypter.SetKey(vMasterKey, chIV))
0127 return false;
0128 return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
0129 }