123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231 |
- /* Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved.
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License, version 2.0,
- as published by the Free Software Foundation.
- This program is also distributed with certain software (including
- but not limited to OpenSSL) that is licensed under separate terms,
- as designated in a particular file or component or in included license
- documentation. The authors of MySQL hereby grant you an additional
- permission to link the program and your derivative works with the
- separately licensed software that they have included with MySQL.
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License, version 2.0, for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
- #ifndef STREAM_CIPHER_INCLUDED
- #define STREAM_CIPHER_INCLUDED
- #include <openssl/evp.h>
- #include <memory>
- #include <string>
- /**
- @file stream_cipher.h
- @brief This file includes core components for encrypting/decrypting
- binary log files.
- */
- typedef std::basic_string<unsigned char> Key_string;
- /**
- @class Stream_cipher
- This abstract class represents the interface of a replication logs encryption
- cipher that can be used to encrypt/decrypt a given stream content in both
- sequential and random way.
- - Sequential means encrypting/decrypting a stream from the begin to end
- in order. For sequential encrypting/decrypting, you just need to call
- it like:
- open();
- encrypt();
- ...
- encrypt(); // call it again and again
- ...
- close();
- - Random means encrypting/decrypting a stream data without order. For
- example:
- - It first encrypts the data of a stream at the offset from 100 to 200.
- - And then encrypts the data of the stream at the offset from 0 to 99.
- For random encrypting/decrypting, you need to call set_stream_offset()
- before calling encrypt(). Example:
- open();
- set_stream_offset(100);
- encrypt(...);
- ...
- set_stream_offset(0);
- encrypt(...)
- close();
- */
- class Stream_cipher {
- public:
- virtual ~Stream_cipher() {}
- /**
- Open the cipher with given password.
- @param[in] password The password which is used to initialize the cipher.
- @param[in] header_size The encrypted stream offset wrt the down stream.
- @retval false Success.
- @retval true Error.
- */
- virtual bool open(const Key_string &password, int header_size) = 0;
- /** Close the cipher. */
- virtual void close() = 0;
- /**
- Encrypt data.
- @param[in] dest The buffer for storing encrypted data. It should be
- at least 'length' bytes.
- @param[in] src The data which will be encrypted.
- @param[in] length Length of the data.
- @retval false Success.
- @retval true Error.
- */
- virtual bool encrypt(unsigned char *dest, const unsigned char *src,
- int length) = 0;
- /**
- Decrypt data.
- @param[in] dest The buffer for storing decrypted data. It should be
- at least 'length' bytes.
- @param[in] src The data which will be decrypted.
- @param[in] length Length of the data.
- @retval false Success.
- @retval true Error.
- */
- virtual bool decrypt(unsigned char *dest, const unsigned char *src,
- int length) = 0;
- /**
- Support encrypting/decrypting data at random position of a stream.
- @param[in] offset The stream offset of the data which will be encrypted/
- decrypted in next encrypt()/decrypt() call.
- @retval false Success.
- @retval true Error.
- */
- virtual bool set_stream_offset(uint64_t offset) = 0;
- /**
- Returns the size of the header of the stream being encrypted/decrypted.
- @return the size of the header of the stream being encrypted/decrypted.
- */
- int get_header_size();
- protected:
- int m_header_size = 0;
- };
- /**
- @class Aes_ctr
- The class provides standards to be used by the Aes_ctr ciphers.
- */
- class Aes_ctr {
- public:
- static const int PASSWORD_LENGTH = 32;
- static const int AES_BLOCK_SIZE = 16;
- static const int FILE_KEY_LENGTH = 32;
- /**
- Returns the message digest function to be uses when opening the cipher.
- @return SHA-512 message digest.
- */
- static const EVP_MD *get_evp_md() { return EVP_sha512(); }
- /**
- Returns the cipher to be uses when using the cipher.
- @return AES-256-CTR.
- */
- static const EVP_CIPHER *get_evp_cipher() { return EVP_aes_256_ctr(); }
- /**
- Returns a new unique Stream_cipher encryptor.
- @return A new Stream_cipher encryptor.
- */
- static std::unique_ptr<Stream_cipher> get_encryptor();
- /**
- Returns a new unique Stream_cipher decryptor.
- @return A new Stream_cipher decryptor.
- */
- static std::unique_ptr<Stream_cipher> get_decryptor();
- };
- enum class Cipher_type : int { ENCRYPT = 0, DECRYPT = 1 };
- /**
- @class Aes_ctr_cipher
- The class implements AES-CTR encryption/decryption. It supports to
- encrypt/decrypt a stream in both sequential and random way.
- */
- template <Cipher_type TYPE>
- class Aes_ctr_cipher : public Stream_cipher {
- public:
- static const int PASSWORD_LENGTH = Aes_ctr::PASSWORD_LENGTH;
- static const int AES_BLOCK_SIZE = Aes_ctr::AES_BLOCK_SIZE;
- static const int FILE_KEY_LENGTH = Aes_ctr::FILE_KEY_LENGTH;
- virtual ~Aes_ctr_cipher() override;
- bool open(const Key_string &password, int header_size) override;
- void close() override;
- bool encrypt(unsigned char *dest, const unsigned char *src,
- int length) override;
- bool decrypt(unsigned char *dest, const unsigned char *src,
- int length) override;
- bool set_stream_offset(uint64_t offset) override;
- private:
- /* Cipher context */
- EVP_CIPHER_CTX *m_ctx = nullptr;
- /* The file key to encrypt/decrypt data. */
- unsigned char m_file_key[FILE_KEY_LENGTH];
- /* The initialization vector (IV) used to encrypt/decrypt data. */
- unsigned char m_iv[AES_BLOCK_SIZE];
- /**
- Initialize OpenSSL cipher related context and IV.
- @param[in] offset The stream offset to compute the AES-CTR counter which
- will be set into IV.
- @retval false Success.
- @retval true Error.
- */
- bool init_cipher(uint64_t offset);
- /** Destroy OpenSSL cipher related context. */
- void deinit_cipher();
- };
- typedef class Aes_ctr_cipher<Cipher_type::ENCRYPT> Aes_ctr_encryptor;
- typedef class Aes_ctr_cipher<Cipher_type::DECRYPT> Aes_ctr_decryptor;
- #endif // STREAM_CIPHER_INCLUDED
|