bitcoin_crypter/crypter.rs
1/*!
2 | Private key encryption is done based on
3 | a CMasterKey, which holds a salt and random
4 | encryption key.
5 |
6 | CMasterKeys are encrypted using AES-256-CBC
7 | using a key derived using derivation method
8 | nDerivationMethod (0 == EVP_sha512()) and
9 | derivation iterations nDeriveIterations.
10 | vchOtherDerivationParameters is provided for
11 | alternative algorithms which may require more
12 | parameters (such as scrypt).
13 |
14 | Wallet Private Keys are then encrypted using
15 | AES-256-CBC with the double-sha256 of the
16 | public key as the IV, and the master key's key
17 | as the encryption key (see keystore.[ch]).
18 */
19
20crate::ix!();
21
22//-------------------------------------------[.cpp/bitcoin/src/wallet/crypter.h]
23//-------------------------------------------[.cpp/bitcoin/src/wallet/crypter.cpp]
24
25pub const WALLET_CRYPTO_KEY_SIZE: u32 = 32;
26pub const WALLET_CRYPTO_SALT_SIZE: u32 = 8;
27pub const WALLET_CRYPTO_IV_SIZE: u32 = 16;
28
29pub type KeyingMaterial = Vec<u8,SecureAllocator>;
30
31/**
32 | Encryption/decryption context with
33 | key information
34 |
35 */
36pub struct Crypter {
37 vch_key: Vec<u8,SecureAllocator>,
38 vchiv: Vec<u8,SecureAllocator>,
39 key_set: bool,
40}
41
42impl Default for Crypter {
43
44 fn default() -> Self {
45 todo!();
46 /*
47
48
49 fKeySet = false;
50 vchKey.resize(WALLET_CRYPTO_KEY_SIZE);
51 vchIV.resize(WALLET_CRYPTO_IV_SIZE);
52 */
53 }
54}
55
56impl Drop for Crypter {
57 fn drop(&mut self) {
58 todo!();
59 /*
60 CleanKey();
61 */
62 }
63}
64
65impl Crypter {
66
67 pub fn clean_key(&mut self) {
68
69 todo!();
70 /*
71 memory_cleanse(vchKey.data(), vchKey.size());
72 memory_cleanse(vchIV.data(), vchIV.size());
73 fKeySet = false;
74 */
75 }
76
77 pub fn bytes_to_keysha512aes(&self,
78 ch_salt: &Vec<u8>,
79 str_key_data: &SecureString,
80 count: i32,
81 key: *mut u8,
82 iv: *mut u8) -> i32 {
83
84 todo!();
85 /*
86 // This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc
87 // cipher and sha512 message digest. Because sha512's output size (64b) is
88 // greater than the aes256 block size (16b) + aes256 key size (32b),
89 // there's no need to process more than once (D_0).
90
91 if(!count || !key || !iv)
92 return 0;
93
94 unsigned char buf[CSHA512::OUTPUT_SIZE];
95 CSHA512 di;
96
97 di.Write((const unsigned char*)strKeyData.data(), strKeyData.size());
98 di.Write(chSalt.data(), chSalt.size());
99 di.Finalize(buf);
100
101 for(int i = 0; i != count - 1; i++)
102 di.Reset().Write(buf, sizeof(buf)).Finalize(buf);
103
104 memcpy(key, buf, WALLET_CRYPTO_KEY_SIZE);
105 memcpy(iv, buf + WALLET_CRYPTO_KEY_SIZE, WALLET_CRYPTO_IV_SIZE);
106 memory_cleanse(buf, sizeof(buf));
107 return WALLET_CRYPTO_KEY_SIZE;
108 */
109 }
110
111 pub fn set_key_from_passphrase(&mut self,
112 str_key_data: &SecureString,
113 ch_salt: &Vec<u8>,
114 n_rounds: u32,
115 n_derivation_method: u32) -> bool {
116
117 todo!();
118 /*
119 if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
120 return false;
121
122 int i = 0;
123 if (nDerivationMethod == 0)
124 i = BytesToKeySHA512AES(chSalt, strKeyData, nRounds, vchKey.data(), vchIV.data());
125
126 if (i != (int)WALLET_CRYPTO_KEY_SIZE)
127 {
128 memory_cleanse(vchKey.data(), vchKey.size());
129 memory_cleanse(vchIV.data(), vchIV.size());
130 return false;
131 }
132
133 fKeySet = true;
134 return true;
135 */
136 }
137
138 pub fn set_key(&mut self,
139 ch_new_key: &KeyingMaterial,
140 ch_newiv: &Vec<u8>) -> bool {
141
142 todo!();
143 /*
144 if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE || chNewIV.size() != WALLET_CRYPTO_IV_SIZE)
145 return false;
146
147 memcpy(vchKey.data(), chNewKey.data(), chNewKey.size());
148 memcpy(vchIV.data(), chNewIV.data(), chNewIV.size());
149
150 fKeySet = true;
151 return true;
152 */
153 }
154
155 pub fn encrypt(&self,
156 vch_plaintext: &KeyingMaterial,
157 vch_ciphertext: &mut Vec<u8>) -> bool {
158
159 todo!();
160 /*
161 if (!fKeySet)
162 return false;
163
164 // max ciphertext len for a n bytes of plaintext is
165 // n + AES_BLOCKSIZE bytes
166 vchCiphertext.resize(vchPlaintext.size() + AES_BLOCKSIZE);
167
168 AES256CBCEncrypt enc(vchKey.data(), vchIV.data(), true);
169 size_t nLen = enc.Encrypt(vchPlaintext.data(), vchPlaintext.size(), vchCiphertext.data());
170 if(nLen < vchPlaintext.size())
171 return false;
172 vchCiphertext.resize(nLen);
173
174 return true;
175 */
176 }
177
178 pub fn decrypt(&self,
179 vch_ciphertext: &Vec<u8>,
180 vch_plaintext: &mut KeyingMaterial) -> bool {
181
182 todo!();
183 /*
184 if (!fKeySet)
185 return false;
186
187 // plaintext will always be equal to or lesser than length of ciphertext
188 int nLen = vchCiphertext.size();
189
190 vchPlaintext.resize(nLen);
191
192 AES256CBCDecrypt dec(vchKey.data(), vchIV.data(), true);
193 nLen = dec.Decrypt(vchCiphertext.data(), vchCiphertext.size(), vchPlaintext.data());
194 if(nLen == 0)
195 return false;
196 vchPlaintext.resize(nLen);
197 return true;
198 */
199 }
200}
201
202pub fn encrypt_secret(
203 master_key: &KeyingMaterial,
204 vch_plaintext: &KeyingMaterial,
205 niv: &u256,
206 vch_ciphertext: &mut Vec<u8>) -> bool {
207
208 todo!();
209 /*
210 CCrypter cKeyCrypter;
211 std::vector<unsigned char> chIV(WALLET_CRYPTO_IV_SIZE);
212 memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE);
213 if(!cKeyCrypter.SetKey(vMasterKey, chIV))
214 return false;
215 return cKeyCrypter.Encrypt(*((const CKeyingMaterial*)&vchPlaintext), vchCiphertext);
216 */
217}
218
219pub fn decrypt_secret(
220 master_key: &KeyingMaterial,
221 vch_ciphertext: &Vec<u8>,
222 niv: &u256,
223 vch_plaintext: &mut KeyingMaterial) -> bool {
224
225 todo!();
226 /*
227 CCrypter cKeyCrypter;
228 std::vector<unsigned char> chIV(WALLET_CRYPTO_IV_SIZE);
229 memcpy(chIV.data(), &nIV, WALLET_CRYPTO_IV_SIZE);
230 if(!cKeyCrypter.SetKey(vMasterKey, chIV))
231 return false;
232 return cKeyCrypter.Decrypt(vchCiphertext, vchPlaintext);
233 */
234}
235
236pub fn decrypt_key(
237 master_key: &KeyingMaterial,
238 vch_crypted_secret: &Vec<u8>,
239 vch_pub_key: &PubKey,
240 key: &mut Key) -> bool {
241
242 todo!();
243 /*
244 CKeyingMaterial vchSecret;
245 if(!DecryptSecret(vMasterKey, vchCryptedSecret, vchPubKey.GetHash(), vchSecret))
246 return false;
247
248 if (vchSecret.size() != 32)
249 return false;
250
251 key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
252 return key.VerifyPubKey(vchPubKey);
253 */
254}