mirror of
https://github.com/MariaDB/server.git
synced 2025-01-18 21:12:26 +01:00
f8cacd03a7
Analysis: Problem was that we did create crypt data for encrypted table but this new crypt data was not written to page 0. Instead a default crypt data was written to page 0 at table creation. Fixed by explicitly writing new crypt data to page 0 after successfull table creation.
390 lines
13 KiB
C
390 lines
13 KiB
C
/*****************************************************************************
|
|
|
|
Copyright (c) 2015, MariaDB Corporation.
|
|
|
|
This program is free software; you can redistribute it and/or modify it under
|
|
the terms of the GNU General Public License as published by the Free Software
|
|
Foundation; version 2 of the License.
|
|
|
|
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 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 Street, Suite 500, Boston, MA 02110-1335 USA
|
|
|
|
*****************************************************************************/
|
|
|
|
/**************************************************//**
|
|
@file include/fil0crypt.h
|
|
The low-level file system encryption support functions
|
|
|
|
Created 04/01/2015 Jan Lindström
|
|
*******************************************************/
|
|
|
|
#ifndef fil0crypt_h
|
|
#define fil0crypt_h
|
|
|
|
/* This key will be used if nothing else is given */
|
|
#define FIL_DEFAULT_ENCRYPTION_KEY 1
|
|
|
|
/** 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;
|
|
|
|
/**
|
|
* CRYPT_SCHEME_UNENCRYPTED
|
|
*
|
|
* Used as intermediate state when convering a space from unencrypted
|
|
* to encrypted
|
|
*/
|
|
/**
|
|
* CRYPT_SCHEME_1
|
|
*
|
|
* xxx is AES_CTR or AES_CBC (or another block cypher with the same key and iv lengths)
|
|
* L = AES_ECB(KEY, IV)
|
|
* CRYPT(PAGE) = xxx(KEY=L, IV=C, PAGE)
|
|
*/
|
|
|
|
#define CRYPT_SCHEME_1 1
|
|
#define CRYPT_SCHEME_1_IV_LEN 16
|
|
#define CRYPT_SCHEME_UNENCRYPTED 0
|
|
|
|
/* Cached L or key for given key_version */
|
|
struct key_struct
|
|
{
|
|
uint key_version; /*!< Version of the key */
|
|
uint key_length; /*!< Key length */
|
|
unsigned char key[MY_AES_MAX_KEY_LENGTH]; /*!< Cached key
|
|
(that is L in CRYPT_SCHEME_1) */
|
|
};
|
|
|
|
struct fil_space_rotate_state_t
|
|
{
|
|
time_t start_time; // time when rotation started
|
|
ulint active_threads; // active threads in space
|
|
ulint next_offset; // next "free" offset
|
|
ulint max_offset; // max offset needing to be rotated
|
|
uint min_key_version_found; // min key version found but not rotated
|
|
lsn_t end_lsn; // max lsn created when rotating this space
|
|
bool starting; // initial write of IV
|
|
bool flushing; // space is being flushed at end of rotate
|
|
struct {
|
|
bool is_active; // is scrubbing active in this space
|
|
time_t last_scrub_completed; // when was last scrub completed
|
|
} scrubbing;
|
|
};
|
|
|
|
struct fil_space_crypt_struct
|
|
{
|
|
ulint type; // CRYPT_SCHEME
|
|
uint keyserver_requests; // no of key requests to key server
|
|
uint key_count; // No of initalized key-structs
|
|
uint key_id; // Key id for this space
|
|
key_struct keys[3]; // cached L = AES_ECB(KEY, IV)
|
|
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
|
|
fil_space_rotate_state_t rotate_state;
|
|
|
|
uint iv_length; // length of IV
|
|
byte iv[1]; // IV-data
|
|
};
|
|
|
|
/* structure containing encryption specification */
|
|
typedef struct fil_space_crypt_struct fil_space_crypt_t;
|
|
|
|
/*********************************************************************
|
|
Init global resources needed for tablespace encryption/decryption */
|
|
UNIV_INTERN
|
|
void
|
|
fil_space_crypt_init();
|
|
|
|
/*********************************************************************
|
|
Cleanup global resources needed for tablespace encryption/decryption */
|
|
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 */
|
|
|
|
/*********************************************************************
|
|
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 */
|
|
|
|
/*********************************************************************
|
|
Set crypt data for a space*/
|
|
UNIV_INTERN
|
|
void
|
|
fil_space_set_crypt_data(
|
|
/*======================*/
|
|
ulint space, /*!< in: tablespace id */
|
|
fil_space_crypt_t* crypt_data); /*!< in: crypt data to set */
|
|
|
|
/*********************************************************************
|
|
Compare crypt data*/
|
|
UNIV_INTERN
|
|
int
|
|
fil_space_crypt_compare(
|
|
/*======================*/
|
|
const fil_space_crypt_t* crypt_data1, /*!< in: crypt data */
|
|
const fil_space_crypt_t* crypt_data2); /*!< in: crypt data */
|
|
|
|
/*********************************************************************
|
|
Read crypt data from buffer page */
|
|
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 */
|
|
|
|
/*********************************************************************
|
|
Write crypt data to buffer page */
|
|
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 */
|
|
|
|
/*********************************************************************
|
|
Clear crypt data from page 0 (used for import tablespace) */
|
|
UNIV_INTERN
|
|
void
|
|
fil_space_clear_crypt_data(
|
|
/*======================*/
|
|
byte* page, /*!< in: buffer page */
|
|
ulint offset); /*!< in: offset where crypt data is stored */
|
|
|
|
/*********************************************************************
|
|
Parse crypt data log record */
|
|
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 */
|
|
|
|
/*********************************************************************
|
|
Check if extra buffer shall be allocated for decrypting after read */
|
|
UNIV_INTERN
|
|
bool
|
|
fil_space_check_encryption_read(
|
|
/*==============================*/
|
|
ulint space); /*!< in: tablespace id */
|
|
|
|
/*********************************************************************
|
|
Check if page shall be encrypted before write */
|
|
UNIV_INTERN
|
|
bool
|
|
fil_space_check_encryption_write(
|
|
/*==============================*/
|
|
ulint space); /*!< in: tablespace id */
|
|
|
|
/*********************************************************************
|
|
Encrypt buffer page */
|
|
UNIV_INTERN
|
|
void
|
|
fil_space_encrypt(
|
|
/*===============*/
|
|
ulint space, /*!< in: tablespace id */
|
|
ulint offset, /*!< in: page no */
|
|
lsn_t lsn, /*!< in: page lsn */
|
|
const byte* src_frame,/*!< in: page frame */
|
|
ulint size, /*!< in: size of data to encrypt */
|
|
byte* dst_frame); /*!< in: where to encrypt to */
|
|
|
|
/*********************************************************************
|
|
Decrypt buffer page */
|
|
UNIV_INTERN
|
|
void
|
|
fil_space_decrypt(
|
|
/*===============*/
|
|
ulint space, /*!< in: tablespace id */
|
|
const byte* src_frame,/*!< in: page frame */
|
|
ulint page_size, /*!< in: size of data to encrypt */
|
|
byte* dst_frame); /*!< in: where to decrypt to */
|
|
|
|
|
|
/*********************************************************************
|
|
Decrypt buffer page
|
|
@return true if page was encrypted */
|
|
UNIV_INTERN
|
|
bool
|
|
fil_space_decrypt(
|
|
/*===============*/
|
|
fil_space_crypt_t* crypt_data, /*!< in: crypt data */
|
|
const byte* src_frame,/*!< in: page frame */
|
|
ulint page_size, /*!< in: page size */
|
|
byte* dst_frame); /*!< in: where to decrypt to */
|
|
|
|
/*********************************************************************
|
|
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 */
|
|
UNIV_INTERN
|
|
bool
|
|
fil_space_verify_crypt_checksum(
|
|
/*===============*/
|
|
const byte* src_frame,/*!< in: page frame */
|
|
ulint zip_size); /*!< in: size of data to encrypt */
|
|
|
|
/*********************************************************************
|
|
Init threads for key rotation */
|
|
UNIV_INTERN
|
|
void
|
|
fil_crypt_threads_init();
|
|
|
|
/*********************************************************************
|
|
Set thread count (e.g start or stops threads) used for key rotation */
|
|
UNIV_INTERN
|
|
void
|
|
fil_crypt_set_thread_cnt(
|
|
/*=====================*/
|
|
uint new_cnt); /*!< in: requested #threads */
|
|
|
|
/*********************************************************************
|
|
End threads for key rotation */
|
|
UNIV_INTERN
|
|
void
|
|
fil_crypt_threads_end();
|
|
|
|
/*********************************************************************
|
|
Cleanup resources for threads for key rotation */
|
|
UNIV_INTERN
|
|
void
|
|
fil_crypt_threads_cleanup();
|
|
|
|
/*********************************************************************
|
|
Set rotate key age */
|
|
UNIV_INTERN
|
|
void
|
|
fil_crypt_set_rotate_key_age(
|
|
/*=====================*/
|
|
uint rotate_age); /*!< in: requested rotate age */
|
|
|
|
/*********************************************************************
|
|
Set rotation threads iops */
|
|
UNIV_INTERN
|
|
void
|
|
fil_crypt_set_rotation_iops(
|
|
/*=====================*/
|
|
uint iops); /*!< in: requested iops */
|
|
|
|
/*********************************************************************
|
|
Mark a space as closing */
|
|
UNIV_INTERN
|
|
void
|
|
fil_space_crypt_mark_space_closing(
|
|
/*===============*/
|
|
ulint space); /*!< in: tablespace id */
|
|
|
|
/*********************************************************************
|
|
Wait for crypt threads to stop accessing space */
|
|
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 */
|
|
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 */
|
|
};
|
|
|
|
/*********************************************************************
|
|
Get crypt status for a space
|
|
@return 0 if crypt data found */
|
|
UNIV_INTERN
|
|
int
|
|
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;
|
|
};
|
|
|
|
/*********************************************************************
|
|
Get crypt rotation 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 */
|
|
};
|
|
|
|
/*********************************************************************
|
|
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 */
|
|
|
|
#ifndef UNIV_NONINL
|
|
#include "fil0crypt.ic"
|
|
#endif
|
|
|
|
#endif /* fil0crypt_h */
|