crypter.h 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. // ECOin - Copyright (c) - 2014/2022 - GPLv3 - epsylon@riseup.net (https://03c8.net)
  2. #ifndef __CRYPTER_H__
  3. #define __CRYPTER_H__
  4. #include "allocators.h" /* for SecureString */
  5. #include "key.h"
  6. #include "serialize.h"
  7. #include <cstring>
  8. const unsigned int WALLET_CRYPTO_KEY_SIZE = 32;
  9. const unsigned int WALLET_CRYPTO_SALT_SIZE = 8;
  10. /*
  11. Private key encryption is done based on a CMasterKey,
  12. which holds a salt and random encryption key.
  13. CMasterKeys are encrypted using AES-256-CBC using a key
  14. derived using derivation method nDerivationMethod
  15. (0 == EVP_sha512()) and derivation iterations nDeriveIterations.
  16. vchOtherDerivationParameters is provided for alternative algorithms
  17. which may require more parameters (such as scrypt).
  18. Wallet Private Keys are then encrypted using AES-256-CBC
  19. with the double-sha256 of the public key as the IV, and the
  20. master key's key as the encryption key (see keystore.[ch]).
  21. */
  22. /** Master key for wallet encryption */
  23. class CMasterKey
  24. {
  25. public:
  26. std::vector<unsigned char> vchCryptedKey;
  27. std::vector<unsigned char> vchSalt;
  28. // 0 = EVP_sha512()
  29. // 1 = scrypt()
  30. unsigned int nDerivationMethod;
  31. unsigned int nDeriveIterations;
  32. // Use this for more parameters to key derivation,
  33. // such as the various parameters to scrypt
  34. std::vector<unsigned char> vchOtherDerivationParameters;
  35. IMPLEMENT_SERIALIZE
  36. (
  37. READWRITE(vchCryptedKey);
  38. READWRITE(vchSalt);
  39. READWRITE(nDerivationMethod);
  40. READWRITE(nDeriveIterations);
  41. READWRITE(vchOtherDerivationParameters);
  42. )
  43. CMasterKey()
  44. {
  45. // 25000 rounds is just under 0.1 seconds on a 1.86 GHz Pentium M
  46. // ie slightly lower than the lowest hardware we need bother supporting
  47. nDeriveIterations = 25000;
  48. nDerivationMethod = 0;
  49. vchOtherDerivationParameters = std::vector<unsigned char>(0);
  50. }
  51. };
  52. typedef std::vector<unsigned char, secure_allocator<unsigned char> > CKeyingMaterial;
  53. /** Encryption/decryption context with key information */
  54. class CCrypter
  55. {
  56. private:
  57. unsigned char chKey[WALLET_CRYPTO_KEY_SIZE];
  58. unsigned char chIV[WALLET_CRYPTO_KEY_SIZE];
  59. bool fKeySet;
  60. public:
  61. bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
  62. bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext);
  63. bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext);
  64. bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);
  65. void CleanKey()
  66. {
  67. std::memset(&chKey, 0, sizeof chKey);
  68. std::memset(&chIV, 0, sizeof chIV);
  69. fKeySet = false;
  70. }
  71. CCrypter()
  72. {
  73. fKeySet = false;
  74. // Try to keep the key data out of swap (and be a bit over-careful to keep the IV that we don't even use out of swap)
  75. // Note that this does nothing about suspend-to-disk (which will put all our key data on disk)
  76. // 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.
  77. LockedPageManager::instance.LockRange(&chKey[0], sizeof chKey);
  78. LockedPageManager::instance.LockRange(&chIV[0], sizeof chIV);
  79. }
  80. ~CCrypter()
  81. {
  82. CleanKey();
  83. LockedPageManager::instance.UnlockRange(&chKey[0], sizeof chKey);
  84. LockedPageManager::instance.UnlockRange(&chIV[0], sizeof chIV);
  85. }
  86. };
  87. bool EncryptSecret(CKeyingMaterial& vMasterKey, const CSecret &vchPlaintext, const uint256& nIV, std::vector<unsigned char> &vchCiphertext);
  88. bool DecryptSecret(const CKeyingMaterial& vMasterKey, const std::vector<unsigned char> &vchCiphertext, const uint256& nIV, CSecret &vchPlaintext);
  89. #endif