Bitcoin ABC 0.26.3
P2P Digital Currency
Loading...
Searching...
No Matches
crypter.cpp
Go to the documentation of this file.
1// Copyright (c) 2009-2016 The Bitcoin Core developers
2// Distributed under the MIT software license, see the accompanying
3// file COPYING or http://www.opensource.org/licenses/mit-license.php.
4
5#include <wallet/crypter.h>
6
7#include <common/system.h>
8#include <crypto/aes.h>
9#include <crypto/sha512.h>
10
11#include <vector>
12
13int CCrypter::BytesToKeySHA512AES(const std::vector<uint8_t> &chSalt,
14 const SecureString &strKeyData, int count,
15 uint8_t *key, uint8_t *iv) const {
16 // This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc
17 // cipher and sha512 message digest. Because sha512's output size (64b) is
18 // greater than the aes256 block size (16b) + aes256 key size (32b), there's
19 // no need to process more than once (D_0).
20 if (!count || !key || !iv) {
21 return 0;
22 }
23
25 CSHA512 di;
26
27 di.Write((const uint8_t *)strKeyData.data(), strKeyData.size());
28 di.Write(chSalt.data(), chSalt.size());
29 di.Finalize(buf);
30
31 for (int i = 0; i != count - 1; i++) {
32 di.Reset().Write(buf, sizeof(buf)).Finalize(buf);
33 }
34
37 memory_cleanse(buf, sizeof(buf));
39}
40
42 const std::vector<uint8_t> &chSalt,
43 const unsigned int nRounds,
44 const unsigned int nDerivationMethod) {
45 if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE) {
46 return false;
47 }
48
49 int i = 0;
50 if (nDerivationMethod == 0) {
52 vchIV.data());
53 }
54
55 if (i != (int)WALLET_CRYPTO_KEY_SIZE) {
56 memory_cleanse(vchKey.data(), vchKey.size());
57 memory_cleanse(vchIV.data(), vchIV.size());
58 return false;
59 }
60
61 fKeySet = true;
62 return true;
63}
64
66 const std::vector<uint8_t> &chNewIV) {
67 if (chNewKey.size() != WALLET_CRYPTO_KEY_SIZE ||
69 return false;
70 }
71
72 memcpy(vchKey.data(), chNewKey.data(), chNewKey.size());
73 memcpy(vchIV.data(), chNewIV.data(), chNewIV.size());
74
75 fKeySet = true;
76 return true;
77}
78
80 std::vector<uint8_t> &vchCiphertext) const {
81 if (!fKeySet) {
82 return false;
83 }
84
85 // max ciphertext len for a n bytes of plaintext is
86 // n + AES_BLOCKSIZE bytes
88
89 AES256CBCEncrypt enc(vchKey.data(), vchIV.data(), true);
90 size_t nLen = enc.Encrypt(vchPlaintext.data(), vchPlaintext.size(),
91 vchCiphertext.data());
92 if (nLen < vchPlaintext.size()) {
93 return false;
94 }
95 vchCiphertext.resize(nLen);
96
97 return true;
98}
99
100bool CCrypter::Decrypt(const std::vector<uint8_t> &vchCiphertext,
102 if (!fKeySet) {
103 return false;
104 }
105
106 // plaintext will always be equal to or lesser than length of ciphertext
107 int nLen = vchCiphertext.size();
108
109 vchPlaintext.resize(nLen);
110
111 AES256CBCDecrypt dec(vchKey.data(), vchIV.data(), true);
112 nLen = dec.Decrypt(vchCiphertext.data(), vchCiphertext.size(),
113 vchPlaintext.data());
114 if (nLen == 0) {
115 return false;
116 }
117 vchPlaintext.resize(nLen);
118 return true;
119}
120
123 std::vector<uint8_t> &vchCiphertext) {
125 std::vector<uint8_t> chIV(WALLET_CRYPTO_IV_SIZE);
127 if (!cKeyCrypter.SetKey(vMasterKey, chIV)) {
128 return false;
129 }
130 return cKeyCrypter.Encrypt(*((const CKeyingMaterial *)&vchPlaintext),
132}
133
135 const std::vector<uint8_t> &vchCiphertext,
138 std::vector<uint8_t> chIV(WALLET_CRYPTO_IV_SIZE);
140 if (!cKeyCrypter.SetKey(vMasterKey, chIV)) {
141 return false;
142 }
143 return cKeyCrypter.Decrypt(vchCiphertext, vchPlaintext);
144}
145
147 const std::vector<uint8_t> &vchCryptedSecret,
148 const CPubKey &vchPubKey, CKey &key) {
151 vchSecret)) {
152 return false;
153 }
154
155 if (vchSecret.size() != 32) {
156 return false;
157 }
158
159 key.Set(vchSecret.begin(), vchSecret.end(), vchPubKey.IsCompressed());
160 return key.VerifyPubKey(vchPubKey);
161}
static const int AES_BLOCKSIZE
Definition aes.h:14
int Decrypt(const uint8_t *data, int size, uint8_t *out) const
Definition aes.cpp:174
int Encrypt(const uint8_t *data, int size, uint8_t *out) const
Definition aes.cpp:158
Encryption/decryption context with key information.
Definition crypter.h:64
std::vector< uint8_t, secure_allocator< uint8_t > > vchKey
Definition crypter.h:69
bool fKeySet
Definition crypter.h:71
bool Encrypt(const CKeyingMaterial &vchPlaintext, std::vector< uint8_t > &vchCiphertext) const
Definition crypter.cpp:79
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector< uint8_t > &chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
Definition crypter.cpp:41
int BytesToKeySHA512AES(const std::vector< uint8_t > &chSalt, const SecureString &strKeyData, int count, uint8_t *key, uint8_t *iv) const
Definition crypter.cpp:13
std::vector< uint8_t, secure_allocator< uint8_t > > vchIV
Definition crypter.h:70
bool Decrypt(const std::vector< uint8_t > &vchCiphertext, CKeyingMaterial &vchPlaintext) const
Definition crypter.cpp:100
bool SetKey(const CKeyingMaterial &chNewKey, const std::vector< uint8_t > &chNewIV)
Definition crypter.cpp:65
An encapsulated secp256k1 private key.
Definition key.h:28
void Set(const T pbegin, const T pend, bool fCompressedIn)
Initialize using begin and end iterators to byte data.
Definition key.h:76
bool VerifyPubKey(const CPubKey &vchPubKey) const
Verify thoroughly whether a private key and a public key match.
Definition key.cpp:302
An encapsulated public key.
Definition pubkey.h:31
bool IsCompressed() const
Check whether this is a compressed public key.
Definition pubkey.h:154
uint256 GetHash() const
Get the 256-bit hash of this public key.
Definition pubkey.h:140
A hasher class for SHA-512.
Definition sha512.h:12
CSHA512 & Write(const uint8_t *data, size_t len)
Definition sha512.cpp:248
static constexpr size_t OUTPUT_SIZE
Definition sha512.h:19
void Finalize(uint8_t hash[OUTPUT_SIZE])
Definition sha512.cpp:273
256-bit opaque blob.
Definition uint256.h:129
void memory_cleanse(void *ptr, size_t len)
Secure overwrite a buffer (possibly containing secret data) with zero-bytes.
Definition cleanse.cpp:14
bool DecryptKey(const CKeyingMaterial &vMasterKey, const std::vector< uint8_t > &vchCryptedSecret, const CPubKey &vchPubKey, CKey &key)
Definition crypter.cpp:146
bool EncryptSecret(const CKeyingMaterial &vMasterKey, const CKeyingMaterial &vchPlaintext, const uint256 &nIV, std::vector< uint8_t > &vchCiphertext)
Definition crypter.cpp:121
bool DecryptSecret(const CKeyingMaterial &vMasterKey, const std::vector< uint8_t > &vchCiphertext, const uint256 &nIV, CKeyingMaterial &vchPlaintext)
Definition crypter.cpp:134
const unsigned int WALLET_CRYPTO_IV_SIZE
Definition crypter.h:14
const unsigned int WALLET_CRYPTO_SALT_SIZE
Definition crypter.h:13
std::vector< uint8_t, secure_allocator< uint8_t > > CKeyingMaterial
Definition crypter.h:57
const unsigned int WALLET_CRYPTO_KEY_SIZE
Definition crypter.h:12
T GetRand(T nMax=std::numeric_limits< T >::max()) noexcept
Generate a uniform random integer of type T in the range [0..nMax) nMax defaults to std::numeric_limi...
Definition random.h:85
std::basic_string< char, std::char_traits< char >, secure_allocator< char > > SecureString
Definition secure.h:55
static int count
Definition tests.c:31