env_encryption_ctr.h 3.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. // Copyright (c) 2016-present, Facebook, Inc. All rights reserved.
  2. // This source code is licensed under both the GPLv2 (found in the
  3. // COPYING file in the root directory) and Apache 2.0 License
  4. // (found in the LICENSE.Apache file in the root directory).
  5. #pragma once
  6. #include "rocksdb/env_encryption.h"
  7. namespace ROCKSDB_NAMESPACE {
  8. // CTRCipherStream implements BlockAccessCipherStream using an
  9. // Counter operations mode.
  10. // See https://en.wikipedia.org/wiki/Block_cipher_mode_of_operation
  11. //
  12. // Note: This is a possible implementation of BlockAccessCipherStream,
  13. // it is considered suitable for use.
  14. class CTRCipherStream final : public BlockAccessCipherStream {
  15. private:
  16. std::shared_ptr<BlockCipher> cipher_;
  17. std::string iv_;
  18. uint64_t initialCounter_;
  19. public:
  20. CTRCipherStream(const std::shared_ptr<BlockCipher>& c, const char* iv,
  21. uint64_t initialCounter)
  22. : cipher_(c), iv_(iv, c->BlockSize()), initialCounter_(initialCounter) {}
  23. virtual ~CTRCipherStream() {}
  24. size_t BlockSize() override { return cipher_->BlockSize(); }
  25. protected:
  26. void AllocateScratch(std::string&) override;
  27. Status EncryptBlock(uint64_t blockIndex, char* data, char* scratch) override;
  28. Status DecryptBlock(uint64_t blockIndex, char* data, char* scratch) override;
  29. };
  30. // This encryption provider uses a CTR cipher stream, with a given block cipher
  31. // and IV.
  32. //
  33. // Note: This is a possible implementation of EncryptionProvider,
  34. // it is considered suitable for use, provided a safe BlockCipher is used.
  35. class CTREncryptionProvider : public EncryptionProvider {
  36. private:
  37. std::shared_ptr<BlockCipher> cipher_;
  38. protected:
  39. // For optimal performance when using direct IO, the prefix length should be a
  40. // multiple of the page size. This size is to ensure the first real data byte
  41. // is placed at largest known alignment point for direct io.
  42. const static size_t defaultPrefixLength = 4096;
  43. public:
  44. explicit CTREncryptionProvider(
  45. const std::shared_ptr<BlockCipher>& c = nullptr);
  46. virtual ~CTREncryptionProvider() {}
  47. static const char* kClassName() { return "CTR"; }
  48. const char* Name() const override { return kClassName(); }
  49. bool IsInstanceOf(const std::string& name) const override;
  50. size_t GetPrefixLength() const override;
  51. Status CreateNewPrefix(const std::string& fname, char* prefix,
  52. size_t prefixLength) const override;
  53. Status CreateCipherStream(
  54. const std::string& fname, const EnvOptions& options, Slice& prefix,
  55. std::unique_ptr<BlockAccessCipherStream>* result) override;
  56. Status AddCipher(const std::string& descriptor, const char* /*cipher*/,
  57. size_t /*len*/, bool /*for_write*/) override;
  58. protected:
  59. // PopulateSecretPrefixPart initializes the data into a new prefix block
  60. // that will be encrypted. This function will store the data in plain text.
  61. // It will be encrypted later (before written to disk).
  62. // Returns the amount of space (starting from the start of the prefix)
  63. // that has been initialized.
  64. virtual size_t PopulateSecretPrefixPart(char* prefix, size_t prefixLength,
  65. size_t blockSize) const;
  66. // CreateCipherStreamFromPrefix creates a block access cipher stream for a
  67. // file given
  68. // given name and options. The given prefix is already decrypted.
  69. virtual Status CreateCipherStreamFromPrefix(
  70. const std::string& fname, const EnvOptions& options,
  71. uint64_t initialCounter, const Slice& iv, const Slice& prefix,
  72. std::unique_ptr<BlockAccessCipherStream>* result);
  73. };
  74. Status NewEncryptedFileSystemImpl(
  75. const std::shared_ptr<FileSystem>& base_fs,
  76. const std::shared_ptr<EncryptionProvider>& provider,
  77. std::unique_ptr<FileSystem>* fs);
  78. } // namespace ROCKSDB_NAMESPACE