Remove unused includes.
[novacoin.git] / src / crypter.cpp
1 // Copyright (c) 2009-2012 The Bitcoin Developers
2 // Distributed under the MIT/X11 software license, see the accompanying
3 // file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5 #include <openssl/aes.h>
6 #include <openssl/evp.h>
7 #include <vector>
8 #include <string>
9
10 #include "crypter.h"
11
12 #ifdef WIN32
13 #include <windows.h>
14 #endif
15
16 bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
17 {
18     if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
19         return false;
20
21     int i = 0;
22     if (nDerivationMethod == 0)
23     {
24         i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0],
25                           (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV);
26     }
27
28     if (i != (int)WALLET_CRYPTO_KEY_SIZE)
29     {
30         OPENSSL_cleanse(&chKey, sizeof chKey);
31         OPENSSL_cleanse(&chIV, sizeof chIV);
32         return false;
33     }
34
35     fKeySet = true;
36     return true;
37 }
38
39 bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV)
40 {
41     if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE)
42         return false;
43
44     memcpy(&chKey[0], &chNewKey[0], sizeof chKey);
45     memcpy(&chIV[0], &chNewIV[0], sizeof chIV);
46
47     fKeySet = true;
48     return true;
49 }
50
51 bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext)
52 {
53     if (!fKeySet)
54         return false;
55
56     // max ciphertext len for a n bytes of plaintext is
57     // n + AES_BLOCK_SIZE - 1 bytes
58     int nLen = vchPlaintext.size();
59     int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0;
60     vchCiphertext = std::vector<unsigned char> (nCLen);
61
62     EVP_CIPHER_CTX ctx;
63
64     bool fOk = true;
65
66     EVP_CIPHER_CTX_init(&ctx);
67     if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0;
68     if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen) != 0;
69     if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0]) + nCLen, &nFLen) != 0;
70     EVP_CIPHER_CTX_cleanup(&ctx);
71
72     if (!fOk) return false;
73
74     vchCiphertext.resize(nCLen + nFLen);
75     return true;
76 }
77
78 bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext)
79 {
80     if (!fKeySet)
81         return false;
82
83     // plaintext will always be equal to or lesser than length of ciphertext
84     int nLen = vchCiphertext.size();
85     int nPLen = nLen, nFLen = 0;
86
87     vchPlaintext = CKeyingMaterial(nPLen);
88
89     EVP_CIPHER_CTX ctx;
90
91     bool fOk = true;
92
93     EVP_CIPHER_CTX_init(&ctx);
94     if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV) != 0;
95     if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen) != 0;
96     if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0]) + nPLen, &nFLen) != 0;
97     EVP_CIPHER_CTX_cleanup(&ctx);
98
99     if (!fOk) return false;
100
101     vchPlaintext.resize(nPLen + nFLen);
102     return true;
103 }
104
105
106 bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext)
107 {
108     CCrypter cKeyCrypter;
109     std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
110     memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
111     if(!cKeyCrypter.SetKey(vMasterKey, chIV))
112         return false;
113     return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext);
114 }
115
116 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext)
117 {
118     CCrypter cKeyCrypter;
119     std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE);
120     memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE);
121     if(!cKeyCrypter.SetKey(vMasterKey, chIV))
122         return false;
123     return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext));
124 }