1 /*********************************************************************** 2 3 Copyright (c) 2019, 2020, Oracle and/or its affiliates. 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License, version 2.0, 7 as published by the Free Software Foundation. 8 9 This program is also distributed with certain software (including 10 but not limited to OpenSSL) that is licensed under separate terms, 11 as designated in a particular file or component or in included license 12 documentation. The authors of MySQL hereby grant you an additional 13 permission to link the program and your derivative works with the 14 separately licensed software that they have included with MySQL. 15 16 This program is distributed in the hope that it will be useful, 17 but WITHOUT ANY WARRANTY; without even the implied warranty of 18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 GNU General Public License, version 2.0, for more details. 20 21 You should have received a copy of the GNU General Public License 22 along with this program; if not, write to the Free Software 23 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 25 ***********************************************************************/ 26 27 /** @file include/os0enc.h 28 Page encryption infrastructure. */ 29 30 #ifndef os0enc_h 31 #define os0enc_h 32 33 #include "univ.i" 34 35 // Forward declaration. 36 class IORequest; 37 38 /** Encryption algorithm. */ 39 class Encryption { 40 public: 41 /** Algorithm types supported */ 42 enum Type { 43 44 /** No encryption */ 45 NONE = 0, 46 47 /** Use AES */ 48 AES = 1, 49 }; 50 51 /** Encryption information format version */ 52 enum Version { 53 54 /** Version in 5.7.11 */ 55 VERSION_1 = 0, 56 57 /** Version in > 5.7.11 */ 58 VERSION_2 = 1, 59 60 /** Version in > 8.0.4 */ 61 VERSION_3 = 2, 62 }; 63 64 /** Encryption magic bytes for 5.7.11, it's for checking the encryption 65 information version. */ 66 static constexpr char KEY_MAGIC_V1[] = "lCA"; 67 68 /** Encryption magic bytes for 5.7.12+, it's for checking the encryption 69 information version. */ 70 static constexpr char KEY_MAGIC_V2[] = "lCB"; 71 72 /** Encryption magic bytes for 8.0.5+, it's for checking the encryption 73 information version. */ 74 static constexpr char KEY_MAGIC_V3[] = "lCC"; 75 76 /** Encryption master key prifix */ 77 static constexpr char MASTER_KEY_PREFIX[] = "INNODBKey"; 78 79 /** Default master key for bootstrap */ 80 static constexpr char DEFAULT_MASTER_KEY[] = "DefaultMasterKey"; 81 82 /** Encryption key length */ 83 static constexpr size_t KEY_LEN = 32; 84 85 /** Encryption magic bytes size */ 86 static constexpr size_t MAGIC_SIZE = 3; 87 88 /** Encryption master key prifix size */ 89 static constexpr size_t MASTER_KEY_PRIFIX_LEN = 9; 90 91 /** Encryption master key prifix size */ 92 static constexpr size_t MASTER_KEY_NAME_MAX_LEN = 100; 93 94 /** UUID of server instance, it's needed for composing master key name */ 95 static constexpr size_t SERVER_UUID_LEN = 36; 96 97 /** Encryption information total size: magic number + master_key_id + 98 key + iv + server_uuid + checksum */ 99 static constexpr size_t INFO_SIZE = 100 (MAGIC_SIZE + sizeof(uint32) + (KEY_LEN * 2) + SERVER_UUID_LEN + 101 sizeof(uint32)); 102 103 /** Maximum size of Encryption information considering all 104 formats v1, v2 & v3. */ 105 static constexpr size_t INFO_MAX_SIZE = INFO_SIZE + sizeof(uint32); 106 107 /** Default master key id for bootstrap */ 108 static constexpr size_t DEFAULT_MASTER_KEY_ID = 0; 109 110 /** (De)Encryption Operation information size */ 111 static constexpr size_t OPERATION_INFO_SIZE = 1; 112 113 /** Encryption Progress information size */ 114 static constexpr size_t PROGRESS_INFO_SIZE = sizeof(uint); 115 116 /** Flag bit to indicate if Encryption/Decryption is in progress */ 117 static constexpr size_t ENCRYPT_IN_PROGRESS = 1 << 0; 118 119 /** Decryption in progress. */ 120 static constexpr size_t DECRYPT_IN_PROGRESS = 1 << 1; 121 122 /** Default constructor */ Encryption()123 Encryption() noexcept : m_type(NONE) {} 124 125 /** Specific constructor 126 @param[in] type Algorithm type */ Encryption(Type type)127 explicit Encryption(Type type) noexcept : m_type(type) { 128 #ifdef UNIV_DEBUG 129 switch (m_type) { 130 case NONE: 131 case AES: 132 133 default: 134 ut_error; 135 } 136 #endif /* UNIV_DEBUG */ 137 } 138 139 /** Copy constructor */ Encryption(const Encryption & other)140 Encryption(const Encryption &other) noexcept 141 : m_type(other.m_type), 142 m_key(other.m_key), 143 m_klen(other.m_klen), 144 m_iv(other.m_iv) {} 145 146 Encryption &operator=(const Encryption &) = default; 147 148 static void set_master_key(ulint master_key_id); 149 150 /** Check if page is encrypted page or not 151 @param[in] page page which need to check 152 @return true if it is an encrypted page */ 153 static bool is_encrypted_page(const byte *page) noexcept 154 MY_ATTRIBUTE((warn_unused_result)); 155 156 /** Check if a log block is encrypted or not 157 @param[in] block block which need to check 158 @return true if it is an encrypted block */ 159 static bool is_encrypted_log(const byte *block) noexcept 160 MY_ATTRIBUTE((warn_unused_result)); 161 162 /** Check the encryption option and set it 163 @param[in] option encryption option 164 @param[in,out] type The encryption type 165 @return DB_SUCCESS or DB_UNSUPPORTED */ 166 dberr_t set_algorithm(const char *option, Encryption *type) noexcept 167 MY_ATTRIBUTE((warn_unused_result)); 168 169 /** Validate the algorithm string. 170 @param[in] option Encryption option 171 @return DB_SUCCESS or error code */ 172 static dberr_t validate(const char *option) noexcept 173 MY_ATTRIBUTE((warn_unused_result)); 174 175 /** Convert to a "string". 176 @param[in] type The encryption type 177 @return the string representation */ 178 static const char *to_string(Type type) noexcept 179 MY_ATTRIBUTE((warn_unused_result)); 180 181 /** Check if the string is "empty" or "none". 182 @param[in] algorithm Encryption algorithm to check 183 @return true if no algorithm requested */ 184 static bool is_none(const char *algorithm) noexcept 185 MY_ATTRIBUTE((warn_unused_result)); 186 187 /** Generate random encryption value for key and iv. 188 @param[in,out] value Encryption value */ 189 static void random_value(byte *value) noexcept; 190 191 /** Create new master key for key rotation. 192 @param[in,out] master_key master key */ 193 static void create_master_key(byte **master_key) noexcept; 194 195 /** Get master key by key id. 196 @param[in] master_key_id master key id 197 @param[in] srv_uuid uuid of server instance 198 @param[in,out] master_key master key */ 199 static void get_master_key(ulint master_key_id, char *srv_uuid, 200 byte **master_key) noexcept; 201 202 /** Get current master key and key id. 203 @param[in,out] master_key_id master key id 204 @param[in,out] master_key master key */ 205 static void get_master_key(ulint *master_key_id, byte **master_key) noexcept; 206 207 /** Fill the encryption information. 208 @param[in] key encryption key 209 @param[in] iv encryption iv 210 @param[in,out] encrypt_info encryption information 211 @param[in] is_boot if it's for bootstrap 212 @param[in] encrypt_key encrypt with master key 213 @return true if success. */ 214 static bool fill_encryption_info(byte *key, byte *iv, byte *encrypt_info, 215 bool is_boot, bool encrypt_key) noexcept; 216 217 /** Get master key from encryption information 218 @param[in] encrypt_info encryption information 219 @param[in] version version of encryption information 220 @param[in,out] m_key_id master key id 221 @param[in,out] srv_uuid server uuid 222 @param[in,out] master_key master key 223 @return position after master key id or uuid, or the old position 224 if can't get the master key. */ 225 static byte *get_master_key_from_info(byte *encrypt_info, Version version, 226 uint32_t *m_key_id, char *srv_uuid, 227 byte **master_key) noexcept; 228 229 /** Decoding the encryption info from the first page of a tablespace. 230 @param[in,out] key key 231 @param[in,out] iv iv 232 @param[in] encryption_info encryption info 233 @param[in] decrypt_key decrypt key using master key 234 @return true if success */ 235 static bool decode_encryption_info(byte *key, byte *iv, byte *encryption_info, 236 bool decrypt_key) noexcept; 237 238 /** Encrypt the redo log block. 239 @param[in] type IORequest 240 @param[in,out] src_ptr log block which need to encrypt 241 @param[in,out] dst_ptr destination area 242 @return true if success. */ 243 bool encrypt_log_block(const IORequest &type, byte *src_ptr, 244 byte *dst_ptr) noexcept; 245 246 /** Encrypt the redo log data contents. 247 @param[in] type IORequest 248 @param[in,out] src page data which need to encrypt 249 @param[in] src_len size of the source in bytes 250 @param[in,out] dst destination area 251 @param[in,out] dst_len size of the destination in bytes 252 @return buffer data, dst_len will have the length of the data */ 253 byte *encrypt_log(const IORequest &type, byte *src, ulint src_len, byte *dst, 254 ulint *dst_len) noexcept; 255 256 /** Encrypt the page data contents. Page type can't be 257 FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED, 258 FIL_PAGE_ENCRYPTED_RTREE. 259 @param[in] type IORequest 260 @param[in,out] src page data which need to encrypt 261 @param[in] src_len size of the source in bytes 262 @param[in,out] dst destination area 263 @param[in,out] dst_len size of the destination in bytes 264 @return buffer data, dst_len will have the length of the data */ 265 byte *encrypt(const IORequest &type, byte *src, ulint src_len, byte *dst, 266 ulint *dst_len) noexcept MY_ATTRIBUTE((warn_unused_result)); 267 268 /** Decrypt the log block. 269 @param[in] type IORequest 270 @param[in,out] src data read from disk, decrypted data 271 will be copied to this page 272 @param[in,out] dst scratch area to use for decryption 273 @return DB_SUCCESS or error code */ 274 dberr_t decrypt_log_block(const IORequest &type, byte *src, 275 byte *dst) noexcept; 276 277 /** Decrypt the log data contents. 278 @param[in] type IORequest 279 @param[in,out] src data read from disk, decrypted data 280 will be copied to this page 281 @param[in] src_len source data length 282 @param[in,out] dst scratch area to use for decryption 283 @param[in] dst_len size of the scratch area in bytes 284 @return DB_SUCCESS or error code */ 285 dberr_t decrypt_log(const IORequest &type, byte *src, ulint src_len, 286 byte *dst, ulint dst_len) noexcept; 287 288 /** Decrypt the page data contents. Page type must be 289 FIL_PAGE_ENCRYPTED, FIL_PAGE_COMPRESSED_AND_ENCRYPTED, 290 FIL_PAGE_ENCRYPTED_RTREE, if not then the source contents are 291 left unchanged and DB_SUCCESS is returned. 292 @param[in] type IORequest 293 @param[in,out] src data read from disk, decrypt 294 data will be copied to this page 295 @param[in] src_len source data length 296 @param[in,out] dst scratch area to use for decrypt 297 @param[in] dst_len size of the scratch area in bytes 298 @return DB_SUCCESS or error code */ 299 dberr_t decrypt(const IORequest &type, byte *src, ulint src_len, byte *dst, 300 ulint dst_len) noexcept MY_ATTRIBUTE((warn_unused_result)); 301 302 /** Check if keyring plugin loaded. */ 303 static bool check_keyring() noexcept; 304 305 /** Get encryption type 306 @return encryption type **/ 307 Type get_type() const; 308 309 /** Set encryption type 310 @param[in] type encryption type **/ 311 void set_type(Type type); 312 313 /** Get encryption key 314 @return encryption key **/ 315 byte *get_key() const; 316 317 /** Set encryption key 318 @param[in] key encryption key **/ 319 void set_key(byte *key); 320 321 /** Get key length 322 @return key length **/ 323 ulint get_key_length() const; 324 325 /** Set key length 326 @param[in] klen key length **/ 327 void set_key_length(ulint klen); 328 329 /** Get initial vector 330 @return initial vector **/ 331 byte *get_initial_vector() const; 332 333 /** Set initial vector 334 @param[in] iv initial_vector **/ 335 void set_initial_vector(byte *iv); 336 337 /** Get master key id 338 @return master key id **/ 339 static ulint get_master_key_id(); 340 341 private: 342 /** Encrypt type */ 343 Type m_type; 344 345 /** Encrypt key */ 346 byte *m_key; 347 348 /** Encrypt key length*/ 349 ulint m_klen; 350 351 /** Encrypt initial vector */ 352 byte *m_iv; 353 354 /** Current master key id */ 355 static ulint s_master_key_id; 356 357 /** Current uuid of server instance */ 358 static char s_uuid[SERVER_UUID_LEN + 1]; 359 }; 360 361 #endif /* os0enc_h */ 362