summaryrefslogtreecommitdiff
path: root/storage/innobase/fil/fil0crypt.cc
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/fil/fil0crypt.cc')
-rw-r--r--storage/innobase/fil/fil0crypt.cc195
1 files changed, 49 insertions, 146 deletions
diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc
index 854037f7df6..d7df8553dcb 100644
--- a/storage/innobase/fil/fil0crypt.cc
+++ b/storage/innobase/fil/fil0crypt.cc
@@ -616,8 +616,7 @@ fil_encrypt_buf(
// store the post-encryption checksum after the key-version
mach_write_to_4(dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4, checksum);
- ut_ad(fil_space_verify_crypt_checksum(dst_frame, page_size,
- space, offset));
+ ut_ad(fil_space_verify_crypt_checksum(dst_frame, page_size));
srv_stats.pages_encrypted.inc();
@@ -2533,164 +2532,68 @@ 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
+@return whether the encrypted page is OK */
bool
-fil_space_verify_crypt_checksum(
- byte* page,
- const page_size_t& page_size,
- ulint space,
- ulint offset)
+fil_space_verify_crypt_checksum(const byte* page, const page_size_t& page_size)
{
- uint key_version = mach_read_from_4(page+ FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION);
-
- /* If page is not encrypted, return false */
- if (key_version == 0) {
- return false;
- }
-
- /* Read stored post encryption checksum. */
- uint32_t checksum = mach_read_from_4(
- page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4);
-
- /* Declare empty pages non-corrupted */
- if (checksum == 0
- && *reinterpret_cast<const ib_uint64_t*>(page + FIL_PAGE_LSN) == 0
- && buf_page_is_zeroes(page, page_size)) {
- return(true);
- }
+ ut_ad(mach_read_from_4(page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION));
/* Compressed and encrypted pages do not have checksum. Assume not
corrupted. Page verification happens after decompression in
buf_page_io_complete() using buf_page_is_corrupted(). */
- if (mach_read_from_2(page+FIL_PAGE_TYPE) == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
- return (true);
+ if (mach_read_from_2(page + FIL_PAGE_TYPE)
+ == FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED) {
+ return true;
}
- uint32_t cchecksum1, cchecksum2;
-
- /* Calculate checksums */
- if (page_size.is_compressed()) {
- cchecksum1 = page_zip_calc_checksum(
- page, page_size.physical(),
- SRV_CHECKSUM_ALGORITHM_CRC32);
-
- cchecksum2 = (cchecksum1 == checksum)
- ? 0
- : page_zip_calc_checksum(
- page, page_size.physical(),
- SRV_CHECKSUM_ALGORITHM_INNODB);
- } else {
- cchecksum1 = buf_calc_page_crc32(page);
- cchecksum2 = (cchecksum1 == checksum)
- ? 0
- : buf_calc_page_new_checksum(page);
- }
+ /* Read stored post encryption checksum. */
+ const ib_uint32_t checksum = mach_read_from_4(
+ page + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + 4);
/* If stored checksum matches one of the calculated checksums
page is not corrupted. */
+ srv_checksum_algorithm_t algorithm = srv_checksum_algorithm_t(
+ srv_checksum_algorithm);
- bool encrypted = (checksum == cchecksum1 || checksum == cchecksum2
- || checksum == BUF_NO_CHECKSUM_MAGIC);
-
- /* MySQL 5.6 and MariaDB 10.0 and 10.1 will write an LSN to the
- first page of each system tablespace file at
- FIL_PAGE_FILE_FLUSH_LSN offset. On other pages and in other files,
- the field might have been uninitialized until MySQL 5.5. In MySQL 5.7
- (and MariaDB Server 10.2.2) WL#7990 stopped writing the field for other
- than page 0 of the system tablespace.
-
- Starting from MariaDB 10.1 the field has been repurposed for
- encryption key_version.
-
- Starting with MySQL 5.7 (and MariaDB Server 10.2), the
- field has been repurposed for SPATIAL INDEX pages for
- FIL_RTREE_SPLIT_SEQ_NUM.
-
- Note that FIL_PAGE_FILE_FLUSH_LSN is not included in the InnoDB page
- checksum.
-
- Thus, FIL_PAGE_FILE_FLUSH_LSN could contain any value. While the
- field would usually be 0 for pages that are not encrypted, we cannot
- assume that a nonzero value means that the page is encrypted.
- Therefore we must validate the page both as encrypted and unencrypted
- when FIL_PAGE_FILE_FLUSH_LSN does not contain 0.
- */
-
- uint32_t checksum1 = mach_read_from_4(page + FIL_PAGE_SPACE_OR_CHKSUM);
- uint32_t checksum2;
+ switch (algorithm) {
+ case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
+ if (page_size.is_compressed()) {
+ return checksum == page_zip_calc_checksum(
+ page, page_size.physical(),
+ SRV_CHECKSUM_ALGORITHM_CRC32);
+ }
- bool valid = false;
+ return checksum == buf_calc_page_crc32(page);
+ case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
+ if (page_size.is_compressed()) {
+ return checksum == page_zip_calc_checksum(
+ page, page_size.physical(),
+ SRV_CHECKSUM_ALGORITHM_INNODB);
+ }
+ return checksum == buf_calc_page_new_checksum(page);
+ case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
+ return checksum == BUF_NO_CHECKSUM_MAGIC;
+ case SRV_CHECKSUM_ALGORITHM_NONE:
+ return true;
+ case SRV_CHECKSUM_ALGORITHM_INNODB:
+ case SRV_CHECKSUM_ALGORITHM_CRC32:
+ if (checksum == BUF_NO_CHECKSUM_MAGIC) {
+ return true;
+ }
+ if (page_size.is_compressed()) {
+ if (checksum == page_zip_calc_checksum(
+ page, page_size.physical(), algorithm)) {
+ return true;
+ }
- if (page_size.is_compressed()) {
- valid = checksum1 == cchecksum1;
- checksum2 = checksum1;
- } else {
- checksum2 = mach_read_from_4(
- page + UNIV_PAGE_SIZE - FIL_PAGE_END_LSN_OLD_CHKSUM);
-
- srv_checksum_algorithm_t algorithm =
- static_cast<srv_checksum_algorithm_t>(
- srv_checksum_algorithm);
- switch (algorithm) {
- case SRV_CHECKSUM_ALGORITHM_STRICT_CRC32:
- valid = buf_page_is_checksum_valid_crc32(
- page, checksum1, checksum2);
- break;
- case SRV_CHECKSUM_ALGORITHM_STRICT_INNODB:
- valid = buf_page_is_checksum_valid_innodb(
- page, checksum1, checksum2);
- break;
- case SRV_CHECKSUM_ALGORITHM_STRICT_NONE:
- case SRV_CHECKSUM_ALGORITHM_CRC32:
- case SRV_CHECKSUM_ALGORITHM_INNODB:
- case SRV_CHECKSUM_ALGORITHM_NONE:
- /* never supported
- innodb_checksum_algorithm=none or strict_none
- for encrypted pages. */
- valid = buf_page_is_checksum_valid_crc32(
- page, checksum1, checksum2)
- || buf_page_is_checksum_valid_innodb(
- page, checksum1, checksum2);
- break;
+ algorithm = algorithm == SRV_CHECKSUM_ALGORITHM_INNODB
+ ? SRV_CHECKSUM_ALGORITHM_CRC32
+ : SRV_CHECKSUM_ALGORITHM_INNODB;
+ return checksum == page_zip_calc_checksum(
+ page, page_size.physical(), algorithm);
}
- }
- if (encrypted && valid) {
- /* If page is encrypted and traditional checksums match,
- page could be still encrypted, or not encrypted and valid or
- corrupted. */
-#ifdef UNIV_INNOCHECKSUM
- fprintf(log_file ? log_file : stderr,
- "Page " ULINTPF ":" ULINTPF " may be corrupted."
- " Post encryption checksum %u"
- " stored [%u:%u] key_version %u\n",
- space, offset, checksum, checksum1, checksum2,
- key_version);
-#else /* UNIV_INNOCHECKSUM */
- ib::error()
- << " Page " << space << ":" << offset
- << " may be corrupted.";
- ib::info()
- << "If encrypted: stored checksum" << checksum
- << " calculated checksum [" << cchecksum1 << ":" << cchecksum2
- << "] key_version " << key_version;
- ib::info()
- << "If unencrypted: stored checksum [" << checksum1
- << ":" << checksum2 << "] calculated crc32 ["
- << buf_calc_page_crc32(page)
-# ifdef INNODB_BUG_ENDIAN_CRC32
- << ":" << buf_calc_page_crc32(page, true)
-# endif /* INNODB_BUG_ENDIAN_CRC32 */
- << "] innodb ["
- << buf_calc_page_old_checksum(page) << ":"
- << buf_calc_page_new_checksum(page) << "] LSN "
- << mach_read_from_4(page + FIL_PAGE_LSN);
-#endif
- encrypted = false;
- }
-
- return(encrypted);
+ return checksum == buf_calc_page_crc32(page)
+ || checksum == buf_calc_page_new_checksum(page);
+ }
}