Mercurial > hg > bitcoin
annotate src/crypter.cpp @ 3646:4314bbfbfee5 draft
Preliminary undo file creation
Create files (one per block) with undo information for the transactions
in it.
author | Pieter Wuille <pieter.wuille@gmail.com> |
---|---|
date | Sat, 23 Jun 2012 14:17:13 +0200 |
parents | 59533c6e6ace |
children |
rev | line source |
---|---|
1818
20667468f95b
Update all copyrights to 2012
Gavin Andresen <gavinandresen@gmail.com>
parents:
1533
diff
changeset
|
1 // Copyright (c) 2009-2012 The Bitcoin Developers |
760 | 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> | |
1390
97bac6569f62
Fix build on windows and mac
Gavin Andresen <gavinandresen@gmail.com>
parents:
760
diff
changeset
|
9 #ifdef WIN32 |
760 | 10 #include <windows.h> |
11 #endif | |
12 | |
13 #include "crypter.h" | |
14 | |
1533
d0ccfedf2957
Implement an mlock()'d string class for storing passphrases
Dylan Noblesmith <nobled@dreamwidth.org>
parents:
1390
diff
changeset
|
15 bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) |
760 | 16 { |
17 if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) | |
18 return false; | |
19 | |
20 int i = 0; | |
21 if (nDerivationMethod == 0) | |
22 i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], | |
23 (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); | |
24 | |
2260
d9b2acb762b4
Fix misc. minor sign-comparison warnings
Jeff Garzik <jeff@garzik.org>
parents:
2162
diff
changeset
|
25 if (i != (int)WALLET_CRYPTO_KEY_SIZE) |
760 | 26 { |
27 memset(&chKey, 0, sizeof chKey); | |
28 memset(&chIV, 0, sizeof chIV); | |
29 return false; | |
30 } | |
31 | |
32 fKeySet = true; | |
33 return true; | |
34 } | |
35 | |
36 bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV) | |
37 { | |
38 if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE) | |
39 return false; | |
40 | |
41 memcpy(&chKey[0], &chNewKey[0], sizeof chKey); | |
42 memcpy(&chIV[0], &chNewIV[0], sizeof chIV); | |
43 | |
44 fKeySet = true; | |
45 return true; | |
46 } | |
47 | |
48 bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) | |
49 { | |
50 if (!fKeySet) | |
51 return false; | |
52 | |
53 // max ciphertext len for a n bytes of plaintext is | |
54 // n + AES_BLOCK_SIZE - 1 bytes | |
55 int nLen = vchPlaintext.size(); | |
56 int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; | |
57 vchCiphertext = std::vector<unsigned char> (nCLen); | |
58 | |
59 EVP_CIPHER_CTX ctx; | |
60 | |
2162
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
61 bool fOk = true; |
760 | 62 |
2162
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
63 EVP_CIPHER_CTX_init(&ctx); |
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
64 if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); |
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
65 if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen); |
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
66 if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen); |
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
67 EVP_CIPHER_CTX_cleanup(&ctx); |
760 | 68 |
2162
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
69 if (!fOk) return false; |
760 | 70 |
71 vchCiphertext.resize(nCLen + nFLen); | |
72 return true; | |
73 } | |
74 | |
75 bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) | |
76 { | |
77 if (!fKeySet) | |
78 return false; | |
79 | |
80 // plaintext will always be equal to or lesser than length of ciphertext | |
81 int nLen = vchCiphertext.size(); | |
82 int nPLen = nLen, nFLen = 0; | |
83 | |
84 vchPlaintext = CKeyingMaterial(nPLen); | |
85 | |
86 EVP_CIPHER_CTX ctx; | |
87 | |
2162
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
88 bool fOk = true; |
760 | 89 |
2162
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
90 EVP_CIPHER_CTX_init(&ctx); |
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
91 if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); |
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
92 if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen); |
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
93 if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen); |
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
94 EVP_CIPHER_CTX_cleanup(&ctx); |
760 | 95 |
2162
d5e317f83474
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
1818
diff
changeset
|
96 if (!fOk) return false; |
760 | 97 |
98 vchPlaintext.resize(nPLen + nFLen); | |
99 return true; | |
100 } | |
101 | |
102 | |
103 bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext) | |
104 { | |
105 CCrypter cKeyCrypter; | |
106 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE); | |
107 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); | |
108 if(!cKeyCrypter.SetKey(vMasterKey, chIV)) | |
109 return false; | |
110 return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext); | |
111 } | |
112 | |
113 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext) | |
114 { | |
115 CCrypter cKeyCrypter; | |
116 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE); | |
117 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); | |
118 if(!cKeyCrypter.SetKey(vMasterKey, chIV)) | |
119 return false; | |
120 return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)); | |
121 } |