用于EagleEye3.0 规则集漏报和误报测试的示例项目,项目收集于github和gitee
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

232 lines
6.7 KiB

5 months ago
/* 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