diff options
Diffstat (limited to 'storage/innobase/include/fil0crypt.h')
-rw-r--r-- | storage/innobase/include/fil0crypt.h | 505 |
1 files changed, 235 insertions, 270 deletions
diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h index d6a6ecb1538..831d61445d8 100644 --- a/storage/innobase/include/fil0crypt.h +++ b/storage/innobase/include/fil0crypt.h @@ -26,6 +26,8 @@ Created 04/01/2015 Jan Lindström #ifndef fil0crypt_h #define fil0crypt_h +#ifndef UNIV_INNOCHECKSUM + #include "os0event.h" #include "my_crypt.h" @@ -40,14 +42,6 @@ static const unsigned char CRYPT_MAGIC[MAGIC_SZ] = { /* This key will be used if nothing else is given */ #define FIL_DEFAULT_ENCRYPTION_KEY ENCRYPTION_KEY_SYSTEM_DATA -/** Enum values for encryption table option */ -typedef enum { - FIL_SPACE_ENCRYPTION_DEFAULT = 0, /* Tablespace encrypted if - srv_encrypt_tables = ON */ - FIL_SPACE_ENCRYPTION_ON = 1, /* Tablespace is encrypted always */ - FIL_SPACE_ENCRYPTION_OFF = 2 /* Tablespace is not encrypted */ -} fil_encryption_t; - extern os_event_t fil_crypt_threads_event; /** @@ -107,23 +101,21 @@ struct fil_space_rotate_state_t } scrubbing; }; -struct fil_space_crypt_struct : st_encryption_scheme +struct fil_space_crypt_t : st_encryption_scheme { public: /** Constructor. Does not initialize the members! The object is expected to be placed in a buffer that has been zero-initialized. */ - fil_space_crypt_struct( + fil_space_crypt_t( uint new_type, uint new_min_key_version, uint new_key_id, - ulint offset, fil_encryption_t new_encryption) : st_encryption_scheme(), min_key_version(new_min_key_version), - page0_offset(offset), + page0_offset(0), encryption(new_encryption), - closing(false), key_found(), rotate_state() { @@ -134,9 +126,9 @@ struct fil_space_crypt_struct : st_encryption_scheme locker = crypt_data_scheme_locker; type = new_type; - if (new_encryption == FIL_SPACE_ENCRYPTION_OFF || + if (new_encryption == FIL_ENCRYPTION_OFF || (!srv_encrypt_tables && - new_encryption == FIL_SPACE_ENCRYPTION_DEFAULT)) { + new_encryption == FIL_ENCRYPTION_DEFAULT)) { type = CRYPT_SCHEME_UNENCRYPTED; } else { type = CRYPT_SCHEME_1; @@ -145,9 +137,8 @@ struct fil_space_crypt_struct : st_encryption_scheme } /** Destructor */ - ~fil_space_crypt_struct() + ~fil_space_crypt_t() { - closing = true; mutex_free(&mutex); } @@ -165,45 +156,37 @@ struct fil_space_crypt_struct : st_encryption_scheme /** Returns true if tablespace should be encrypted */ bool should_encrypt() const { - return ((encryption == FIL_SPACE_ENCRYPTION_ON) || + return ((encryption == FIL_ENCRYPTION_ON) || (srv_encrypt_tables && - encryption == FIL_SPACE_ENCRYPTION_DEFAULT)); + encryption == FIL_ENCRYPTION_DEFAULT)); } /** Return true if tablespace is encrypted. */ bool is_encrypted() const { - return (encryption != FIL_SPACE_ENCRYPTION_OFF); + return (encryption != FIL_ENCRYPTION_OFF); } /** Return true if default tablespace encryption is used, */ bool is_default_encryption() const { - return (encryption == FIL_SPACE_ENCRYPTION_DEFAULT); + return (encryption == FIL_ENCRYPTION_DEFAULT); } /** Return true if tablespace is not encrypted. */ bool not_encrypted() const { - return (encryption == FIL_SPACE_ENCRYPTION_OFF); + return (encryption == FIL_ENCRYPTION_OFF); } - /** Is this tablespace closing. */ - bool is_closing(bool is_fixed) { - bool closed; - if (!is_fixed) { - mutex_enter(&mutex); - } - closed = closing; - if (!is_fixed) { - mutex_exit(&mutex); - } - return closed; - } + /** Write crypt data to a page (0) + @param[in] space tablespace + @param[in,out] page0 first page of the tablespace + @param[in,out] mtr mini-transaction */ + void write_page0(const fil_space_t* space, byte* page0, mtr_t* mtr); uint min_key_version; // min key version for this space ulint page0_offset; // byte offset on page 0 for crypt data fil_encryption_t encryption; // Encryption setup ib_mutex_t mutex; // mutex protecting following variables - bool closing; // is tablespace being closed /** Return code from encryption_key_get_latest_version. If ENCRYPTION_KEY_VERSION_INVALID encryption plugin @@ -215,324 +198,306 @@ struct fil_space_crypt_struct : st_encryption_scheme fil_space_rotate_state_t rotate_state; }; -/* structure containing encryption specification */ -typedef struct fil_space_crypt_struct fil_space_crypt_t; +/** Status info about encryption */ +struct fil_space_crypt_status_t { + ulint space; /*!< tablespace id */ + ulint scheme; /*!< encryption scheme */ + uint min_key_version; /*!< min key version */ + uint current_key_version;/*!< current key version */ + uint keyserver_requests;/*!< no of key requests to key server */ + ulint key_id; /*!< current key_id */ + bool rotating; /*!< is key rotation ongoing */ + bool flushing; /*!< is flush at end of rotation ongoing */ + ulint rotate_next_page_number; /*!< next page if key rotating */ + ulint rotate_max_page_number; /*!< max page if key rotating */ +}; + +/** Statistics about encryption key rotation */ +struct fil_crypt_stat_t { + ulint pages_read_from_cache; + ulint pages_read_from_disk; + ulint pages_modified; + ulint pages_flushed; + ulint estimated_iops; +}; + +/** Status info about scrubbing */ +struct fil_space_scrub_status_t { + ulint space; /*!< tablespace id */ + bool compressed; /*!< is space compressed */ + time_t last_scrub_completed; /*!< when was last scrub completed */ + bool scrubbing; /*!< is scrubbing ongoing */ + time_t current_scrub_started; /*!< when started current scrubbing */ + ulint current_scrub_active_threads; /*!< current scrub active threads */ + ulint current_scrub_page_number; /*!< current scrub page no */ + ulint current_scrub_max_page_number; /*!< current scrub max page no */ +}; /********************************************************************* -Init global resources needed for tablespace encryption/decryption */ +Init space crypt */ UNIV_INTERN void fil_space_crypt_init(); /********************************************************************* -Cleanup global resources needed for tablespace encryption/decryption */ +Cleanup space crypt */ UNIV_INTERN void fil_space_crypt_cleanup(); -/********************************************************************* -Create crypt data, i.e data that is used for a single tablespace */ -UNIV_INTERN -fil_space_crypt_t * -fil_space_create_crypt_data( -/*========================*/ - fil_encryption_t encrypt_mode, /*!< in: encryption mode */ - uint key_id) /*!< in: encryption key id */ - __attribute__((warn_unused_result)); - -/********************************************************************* -Destroy crypt data */ -UNIV_INTERN -void -fil_space_destroy_crypt_data( -/*=========================*/ - fil_space_crypt_t **crypt_data); /*!< in/out: crypt data */ - -/********************************************************************* -Get crypt data for a space*/ -UNIV_INTERN -fil_space_crypt_t * -fil_space_get_crypt_data( -/*=====================*/ - ulint space); /*!< in: tablespace id */ +/** +Create a fil_space_crypt_t object +@param[in] encrypt_mode FIL_ENCRYPTION_DEFAULT or + FIL_ENCRYPTION_ON or + FIL_ENCRYPTION_OFF -/********************************************************************* -Set crypt data for a space*/ +@param[in] key_id Encryption key id +@return crypt object */ UNIV_INTERN fil_space_crypt_t* -fil_space_set_crypt_data( -/*=====================*/ - ulint space, /*!< in: tablespace id */ - fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */ +fil_space_create_crypt_data( + fil_encryption_t encrypt_mode, + uint key_id) + MY_ATTRIBUTE((warn_unused_result)); -/********************************************************************* -Merge crypt data */ +/****************************************************************** +Merge fil_space_crypt_t object +@param[in,out] dst Destination cryp data +@param[in] src Source crypt data */ UNIV_INTERN void fil_space_merge_crypt_data( -/*=======================*/ - fil_space_crypt_t* dst_crypt_data, /*!< in: crypt_data */ - const fil_space_crypt_t* src_crypt_data); /*!< in: crypt data */ - -/********************************************************************* -Read crypt data from buffer page */ + fil_space_crypt_t* dst, + const fil_space_crypt_t* src); + +/** Initialize encryption parameters from a tablespace header page. +@param[in] page_size page size of the tablespace +@param[in] page first page of the tablespace +@return crypt data from page 0 +@retval NULL if not present or not valid */ UNIV_INTERN -fil_space_crypt_t * -fil_space_read_crypt_data( -/*======================*/ - ulint space, /*!< in: tablespace id */ - const byte* page, /*!< in: buffer page */ - ulint offset); /*!< in: offset where crypt data is stored */ +fil_space_crypt_t* +fil_space_read_crypt_data(const page_size_t& page_size, const byte* page) + MY_ATTRIBUTE((nonnull, warn_unused_result)); -/********************************************************************* -Write crypt data to buffer page */ +/** +Free a crypt data object +@param[in,out] crypt_data crypt data to be freed */ UNIV_INTERN void -fil_space_write_crypt_data( -/*=======================*/ - ulint space, /*!< in: tablespace id */ - byte* page, /*!< in: buffer page */ - ulint offset, /*!< in: offset where to store data */ - ulint maxsize, /*!< in: max space available to store crypt data in */ - mtr_t * mtr); /*!< in: mini-transaction */ +fil_space_destroy_crypt_data( + fil_space_crypt_t **crypt_data); -/********************************************************************* -Clear crypt data from page 0 (used for import tablespace) */ +/****************************************************************** +Parse a MLOG_FILE_WRITE_CRYPT_DATA log entry +@param[in] ptr Log entry start +@param[in] end_ptr Log entry end +@param[in] block buffer block +@return position on log buffer */ UNIV_INTERN -void -fil_space_clear_crypt_data( -/*=======================*/ - byte* page, /*!< in: buffer page */ - ulint offset); /*!< in: offset where crypt data is stored */ +const byte* +fil_parse_write_crypt_data( + const byte* ptr, + const byte* end_ptr, + const buf_block_t* block) + MY_ATTRIBUTE((warn_unused_result)); + +/** Encrypt a buffer. +@param[in,out] crypt_data Crypt data +@param[in] space space_id +@param[in] offset Page offset +@param[in] lsn Log sequence number +@param[in] src_frame Page to encrypt +@param[in] page_size Page size +@param[in,out] dst_frame Output buffer +@return encrypted buffer or NULL */ +byte* +fil_encrypt_buf( + fil_space_crypt_t* crypt_data, + ulint space, + ulint offset, + lsn_t lsn, + const byte* src_frame, + const page_size_t& page_size, + byte* dst_frame) + MY_ATTRIBUTE((warn_unused_result)); -/********************************************************************* -Parse crypt data log record */ +/** +Encrypt a page. + +@param[in] space Tablespace +@param[in] offset Page offset +@param[in] lsn Log sequence number +@param[in] src_frame Page to encrypt +@param[in,out] dst_frame Output buffer +@return encrypted buffer or NULL */ UNIV_INTERN byte* -fil_parse_write_crypt_data( -/*=======================*/ - byte* ptr, /*!< in: start of log record */ - byte* end_ptr, /*!< in: end of log record */ - buf_block_t*); /*!< in: buffer page to apply record to */ +fil_space_encrypt( + const fil_space_t* space, + ulint offset, + lsn_t lsn, + byte* src_frame, + byte* dst_frame) + MY_ATTRIBUTE((warn_unused_result)); -/********************************************************************* -Check if extra buffer shall be allocated for decrypting after read */ +/** +Decrypt a page. +@param[in,out] crypt_data crypt_data +@param[in] tmp_frame Temporary buffer +@param[in] page_size Page size +@param[in,out] src_frame Page to decrypt +@param[out] err DB_SUCCESS or error +@return true if page decrypted, false if not.*/ UNIV_INTERN bool -fil_space_check_encryption_read( -/*============================*/ - ulint space) /*!< in: tablespace id */ - __attribute__((warn_unused_result)); +fil_space_decrypt( + fil_space_crypt_t* crypt_data, + byte* tmp_frame, + const page_size_t& page_size, + byte* src_frame, + dberr_t* err); /****************************************************************** Decrypt a page -@return true if page is decrypted, false if not. */ -UNIV_INTERN -bool -fil_space_decrypt( -/*==============*/ - fil_space_crypt_t* crypt_data, /*!< in: crypt data */ - byte* tmp_frame, /*!< in: temporary buffer */ - const page_size_t& page_size, /*!< in: page size */ - byte* src_frame, /*!< in:out: page buffer */ - dberr_t* err) /*!< in: out: DB_SUCCESS or - error code */ - __attribute__((warn_unused_result)); - -/********************************************************************* -Encrypt buffer page -@return encrypted page, or original not encrypted page if encrypt -is not needed. */ -UNIV_INTERN -byte* -fil_space_encrypt( -/*==============*/ - ulint space, /*!< in: tablespace id */ - ulint offset, /*!< in: page no */ - lsn_t lsn, /*!< in: page lsn */ - byte* src_frame, /*!< in: page frame */ - const page_size_t& page_size, /*!< in: page size */ - byte* dst_frame) /*!< in: where to encrypt to */ - __attribute__((warn_unused_result)); - -/********************************************************************* -Decrypt buffer page -@return decrypted page, or original not encrypted page if decrypt is +@param[in] space Tablespace +@param[in] tmp_frame Temporary buffer used for decrypting +@param[in,out] src_frame Page to decrypt +@param[out] decrypted true if page was decrypted +@return decrypted page, or original not encrypted page if decryption is not needed.*/ UNIV_INTERN byte* fil_space_decrypt( -/*==============*/ - ulint space, /*!< in: tablespace id */ - byte* src_frame, /*!< in: page frame */ - const page_size_t& page_size, /*!< in: page size */ - byte* dst_frame) /*!< in: where to decrypt to */ - __attribute__((warn_unused_result)); + const fil_space_t* space, + byte* tmp_frame, + byte* src_frame, + bool* decrypted) + MY_ATTRIBUTE((warn_unused_result)); -/********************************************************************* -fil_space_verify_crypt_checksum -NOTE: currently this function can only be run in single threaded mode -as it modifies srv_checksum_algorithm (temporarily) -@return true if page is encrypted AND OK, false otherwise */ +/****************************************************************** +Calculate post encryption checksum +@param[in] page_size page size +@param[in] dst_frame Block where checksum is calculated +@return page checksum or BUF_NO_CHECKSUM_MAGIC +not needed. */ UNIV_INTERN -bool -fil_space_verify_crypt_checksum( -/*============================*/ - const byte* src_frame,/*!< in: page frame */ - const page_size_t& page_size) /*!< in: page size */ - __attribute__((warn_unused_result)); +ulint +fil_crypt_calculate_checksum( + const page_size_t& page_size, + const byte* dst_frame) + MY_ATTRIBUTE((warn_unused_result)); /********************************************************************* -Init threads for key rotation */ +Adjust thread count for key rotation +@param[in] enw_cnt Number of threads to be used */ UNIV_INTERN void -fil_crypt_threads_init(); +fil_crypt_set_thread_cnt( + uint new_cnt); /********************************************************************* -Set thread count (e.g start or stops threads) used for key rotation */ +Adjust max key age +@param[in] val New max key age */ UNIV_INTERN void -fil_crypt_set_thread_cnt( -/*=====================*/ - uint new_cnt); /*!< in: requested #threads */ +fil_crypt_set_rotate_key_age( + uint val); /********************************************************************* -Cleanup resources for threads for key rotation */ +Adjust rotation iops +@param[in] val New max roation iops */ UNIV_INTERN void -fil_crypt_threads_cleanup(); +fil_crypt_set_rotation_iops( + uint val); /********************************************************************* -Set rotate key age */ +Adjust encrypt tables +@param[in] val New setting for innodb-encrypt-tables */ UNIV_INTERN void -fil_crypt_set_rotate_key_age( -/*=========================*/ - uint rotate_age); /*!< in: requested rotate age */ +fil_crypt_set_encrypt_tables( + uint val); /********************************************************************* -Set rotation threads iops */ +Init threads for key rotation */ UNIV_INTERN void -fil_crypt_set_rotation_iops( -/*========================*/ - uint iops); /*!< in: requested iops */ +fil_crypt_threads_init(); /********************************************************************* -Mark a space as closing */ +Clean up key rotation threads resources */ UNIV_INTERN void -fil_space_crypt_mark_space_closing( -/*===============================*/ - ulint space, /*!< in: tablespace id */ - fil_space_crypt_t* crypt_data); /*!< in: crypt_data or NULL */ +fil_crypt_threads_cleanup(); /********************************************************************* -Wait for crypt threads to stop accessing space */ +Wait for crypt threads to stop accessing space +@param[in] space Tablespace */ UNIV_INTERN void fil_space_crypt_close_tablespace( -/*=============================*/ - ulint space); /*!< in: tablespace id */ - -/** Struct for retreiving info about encryption */ -struct fil_space_crypt_status_t { - ulint space; /*!< tablespace id */ - ulint scheme; /*!< encryption scheme */ - uint min_key_version; /*!< min key version */ - uint current_key_version;/*!< current key version */ - uint keyserver_requests;/*!< no of key requests to key server */ - ulint key_id; /*!< current key_id */ - bool rotating; /*!< is key rotation ongoing */ - bool flushing; /*!< is flush at end of rotation ongoing */ - ulint rotate_next_page_number; /*!< next page if key rotating */ - ulint rotate_max_page_number; /*!< max page if key rotating */ -}; + const fil_space_t* space); /********************************************************************* -Get crypt status for a space -@return 0 if crypt data found */ +Get crypt status for a space (used by information_schema) +@param[in] space Tablespace +@param[out] status Crypt status +return 0 if crypt data present */ UNIV_INTERN -int +void fil_space_crypt_get_status( -/*=======================*/ - ulint id, /*!< in: space id */ - struct fil_space_crypt_status_t * status); /*!< out: status */ - -/** Struct for retreiving statistics about encryption key rotation */ -struct fil_crypt_stat_t { - ulint pages_read_from_cache; - ulint pages_read_from_disk; - ulint pages_modified; - ulint pages_flushed; - ulint estimated_iops; -}; + const fil_space_t* space, + struct fil_space_crypt_status_t* status); /********************************************************************* -Get crypt rotation statistics */ +Return crypt statistics +@param[out] stat Crypt statistics */ UNIV_INTERN void fil_crypt_total_stat( -/*==================*/ - fil_crypt_stat_t* stat); /*!< out: crypt stat */ - -/** Struct for retreiving info about scrubbing */ -struct fil_space_scrub_status_t { - ulint space; /*!< tablespace id */ - bool compressed; /*!< is space compressed */ - time_t last_scrub_completed; /*!< when was last scrub completed */ - bool scrubbing; /*!< is scrubbing ongoing */ - time_t current_scrub_started; /*!< when started current scrubbing */ - ulint current_scrub_active_threads; /*!< current scrub active threads */ - ulint current_scrub_page_number; /*!< current scrub page no */ - ulint current_scrub_max_page_number; /*!< current scrub max page no */ -}; + fil_crypt_stat_t *stat); -/********************************************************************* -Get scrub status for a space -@return 0 if no scrub info found */ -UNIV_INTERN -int -fil_space_get_scrub_status( -/*=======================*/ - ulint id, /*!< in: space id */ - struct fil_space_scrub_status_t * status); /*!< out: status */ +/** +Get scrub status for a space (used by information_schema) -/********************************************************************* -Adjust encrypt tables */ +@param[in] space Tablespace +@param[out] status Scrub status +return 0 if data found */ UNIV_INTERN void -fil_crypt_set_encrypt_tables( -/*=========================*/ - uint val); /*!< in: New srv_encrypt_tables setting */ +fil_space_get_scrub_status( + const fil_space_t* space, + fil_space_scrub_status_t* status); -/****************************************************************** -Encrypt a buffer */ -UNIV_INTERN -byte* -fil_encrypt_buf( -/*============*/ - fil_space_crypt_t* crypt_data, /*!< in: crypt data */ - ulint space, /*!< in: Space id */ - ulint offset, /*!< in: Page offset */ - lsn_t lsn, /*!< in: lsn */ - byte* src_frame, /*!< in: Source page to be encrypted */ - const page_size_t& page_size, /*!< in: page size */ - byte* dst_frame) /*!< in: outbut buffer */ - __attribute__((warn_unused_result)); +#include "fil0crypt.ic" +#endif /* !UNIV_INNOCHECKSUM */ -/****************************************************************** -Calculate post encryption checksum -@return page checksum or BUF_NO_CHECKSUM_MAGIC -not needed. */ +/** +Verify that post encryption checksum match calculated checksum. +This function should be called only if tablespace contains crypt_data +metadata (this is strong indication that tablespace is encrypted). +Function also verifies that traditional checksum does not match +calculated checksum as if it does page could be valid unencrypted, +encrypted, or corrupted. + +@param[in,out] page page frame (checksum is temporarily modified) +@param[in] page_size page size +@param[in] space tablespace identifier +@param[in] offset page number +@return true if page is encrypted AND OK, false otherwise */ UNIV_INTERN -ulint -fil_crypt_calculate_checksum( -/*=========================*/ - const page_size_t& page_size, /*!< in: page size */ - byte* dst_frame) /*!< in: page where to calculate */ - __attribute__((warn_unused_result)); - -#include "fil0crypt.ic" +bool +fil_space_verify_crypt_checksum( + byte* page, + const page_size_t& page_size, +#ifdef UNIV_INNOCHECKSUM + bool strict_check, /*!< --strict-check */ + FILE* log_file, /*!< --log */ +#endif /* UNIV_INNOCHECKSUM */ + ulint space, + ulint offset) + MY_ATTRIBUTE((warn_unused_result)); #endif /* fil0crypt_h */ |