Mercurial > hg > bitcoin
annotate src/crypter.cpp @ 2968:04987f8907d6 draft
Merge branch '0.5.x' into 0.6.0.x
Conflicts:
src/main.cpp
author | Luke Dashjr <luke-jr+git@utopios.org> |
---|---|
date | Fri, 04 May 2012 19:55:54 +0000 |
parents | 380b719106a8 |
children | 6d9afd854c97 |
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> | |
9 #include "headers.h" | |
1390
97bac6569f62
Fix build on windows and mac
Gavin Andresen <gavinandresen@gmail.com>
parents:
760
diff
changeset
|
10 #ifdef WIN32 |
760 | 11 #include <windows.h> |
12 #endif | |
13 | |
14 #include "crypter.h" | |
15 #include "main.h" | |
16 #include "util.h" | |
17 | |
1533
d0ccfedf2957
Implement an mlock()'d string class for storing passphrases
Dylan Noblesmith <nobled@dreamwidth.org>
parents:
1390
diff
changeset
|
18 bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod) |
760 | 19 { |
20 if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) | |
21 return false; | |
22 | |
23 // 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) | |
24 // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) | |
25 // 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. | |
26 mlock(&chKey[0], sizeof chKey); | |
27 mlock(&chIV[0], sizeof chIV); | |
28 | |
29 int i = 0; | |
30 if (nDerivationMethod == 0) | |
31 i = EVP_BytesToKey(EVP_aes_256_cbc(), EVP_sha512(), &chSalt[0], | |
32 (unsigned char *)&strKeyData[0], strKeyData.size(), nRounds, chKey, chIV); | |
33 | |
2930
b2958cc2cbd6
Fix misc. minor sign-comparison warnings
Jeff Garzik <jeff@garzik.org>
parents:
2877
diff
changeset
|
34 if (i != (int)WALLET_CRYPTO_KEY_SIZE) |
760 | 35 { |
36 memset(&chKey, 0, sizeof chKey); | |
37 memset(&chIV, 0, sizeof chIV); | |
38 return false; | |
39 } | |
40 | |
41 fKeySet = true; | |
42 return true; | |
43 } | |
44 | |
45 bool CCrypter::SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV) | |
46 { | |
47 if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_KEY_SIZE) | |
48 return false; | |
49 | |
50 // Try to keep the keydata out of swap | |
51 // Note that this does nothing about suspend-to-disk (which will put all our key data on disk) | |
52 // 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. | |
53 mlock(&chKey[0], sizeof chKey); | |
54 mlock(&chIV[0], sizeof chIV); | |
55 | |
56 memcpy(&chKey[0], &chNewKey[0], sizeof chKey); | |
57 memcpy(&chIV[0], &chNewIV[0], sizeof chIV); | |
58 | |
59 fKeySet = true; | |
60 return true; | |
61 } | |
62 | |
63 bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) | |
64 { | |
65 if (!fKeySet) | |
66 return false; | |
67 | |
68 // max ciphertext len for a n bytes of plaintext is | |
69 // n + AES_BLOCK_SIZE - 1 bytes | |
70 int nLen = vchPlaintext.size(); | |
71 int nCLen = nLen + AES_BLOCK_SIZE, nFLen = 0; | |
72 vchCiphertext = std::vector<unsigned char> (nCLen); | |
73 | |
74 EVP_CIPHER_CTX ctx; | |
75 | |
2877
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
76 bool fOk = true; |
760 | 77 |
2877
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
78 EVP_CIPHER_CTX_init(&ctx); |
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
79 if (fOk) fOk = EVP_EncryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); |
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
80 if (fOk) fOk = EVP_EncryptUpdate(&ctx, &vchCiphertext[0], &nCLen, &vchPlaintext[0], nLen); |
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
81 if (fOk) fOk = EVP_EncryptFinal_ex(&ctx, (&vchCiphertext[0])+nCLen, &nFLen); |
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
82 EVP_CIPHER_CTX_cleanup(&ctx); |
760 | 83 |
2877
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
84 if (!fOk) return false; |
760 | 85 |
86 vchCiphertext.resize(nCLen + nFLen); | |
87 return true; | |
88 } | |
89 | |
90 bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) | |
91 { | |
92 if (!fKeySet) | |
93 return false; | |
94 | |
95 // plaintext will always be equal to or lesser than length of ciphertext | |
96 int nLen = vchCiphertext.size(); | |
97 int nPLen = nLen, nFLen = 0; | |
98 | |
99 vchPlaintext = CKeyingMaterial(nPLen); | |
100 | |
101 EVP_CIPHER_CTX ctx; | |
102 | |
2877
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
103 bool fOk = true; |
760 | 104 |
2877
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
105 EVP_CIPHER_CTX_init(&ctx); |
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
106 if (fOk) fOk = EVP_DecryptInit_ex(&ctx, EVP_aes_256_cbc(), NULL, chKey, chIV); |
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
107 if (fOk) fOk = EVP_DecryptUpdate(&ctx, &vchPlaintext[0], &nPLen, &vchCiphertext[0], nLen); |
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
108 if (fOk) fOk = EVP_DecryptFinal_ex(&ctx, (&vchPlaintext[0])+nPLen, &nFLen); |
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
109 EVP_CIPHER_CTX_cleanup(&ctx); |
760 | 110 |
2877
843b53c1c3d1
Verify status of encrypt/decrypt calls to detect failed padding
Pieter Wuille <pieter.wuille@gmail.com>
parents:
760
diff
changeset
|
111 if (!fOk) return false; |
760 | 112 |
113 vchPlaintext.resize(nPLen + nFLen); | |
114 return true; | |
115 } | |
116 | |
117 | |
118 bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext) | |
119 { | |
120 CCrypter cKeyCrypter; | |
121 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE); | |
122 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); | |
123 if(!cKeyCrypter.SetKey(vMasterKey, chIV)) | |
124 return false; | |
125 return cKeyCrypter.Encrypt((CKeyingMaterial)vchPlaintext, vchCiphertext); | |
126 } | |
127 | |
128 bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char>& vchCiphertext, const uint256& nIV, CSecret& vchPlaintext) | |
129 { | |
130 CCrypter cKeyCrypter; | |
131 std::vector<unsigned char> chIV(WALLET_CRYPTO_KEY_SIZE); | |
132 memcpy(&chIV[0], &nIV, WALLET_CRYPTO_KEY_SIZE); | |
133 if(!cKeyCrypter.SetKey(vMasterKey, chIV)) | |
134 return false; | |
135 return cKeyCrypter.Decrypt(vchCiphertext, *((CKeyingMaterial*)&vchPlaintext)); | |
136 } |