Commit 70f0dbe4 authored by Marko Mäkelä's avatar Marko Mäkelä

Cleanup: log upgrade and encryption

log_crypt_101_read_checkpoint(), log_crypt_101_read_block():
Declare as ATTRIBUTE_COLD. These are only used when
checking that a MariaDB 10.1 encrypted redo log is clean.

log_block_calc_checksum_format_0(): Define in the only
compilation unit where it is needed. This is only used
when reading the checkpoint information from redo logs
before MariaDB 10.2.2.

crypt_info_t: Declare the byte arrays directly with alignas().

log_crypt(): Use memcpy_aligned instead of reinterpret_cast
on integers.
parent 522fbfcb
/***************************************************************************** /*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
Copyright (C) 2014, 2018, MariaDB Corporation. Copyright (C) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -55,22 +55,18 @@ log_crypt_write_checkpoint_buf( ...@@ -55,22 +55,18 @@ log_crypt_write_checkpoint_buf(
/** Read the MariaDB 10.1 checkpoint crypto (version, msg and iv) info. /** Read the MariaDB 10.1 checkpoint crypto (version, msg and iv) info.
@param[in] buf checkpoint buffer @param[in] buf checkpoint buffer
@return whether the operation was successful */ @return whether the operation was successful */
UNIV_INTERN ATTRIBUTE_COLD bool log_crypt_101_read_checkpoint(const byte* buf);
bool
log_crypt_101_read_checkpoint(const byte* buf);
/** Decrypt a MariaDB 10.1 redo log block. /** Decrypt a MariaDB 10.1 redo log block.
@param[in,out] buf log block @param[in,out] buf log block
@param[in] start_lsn server start LSN @param[in] start_lsn server start LSN
@return whether the decryption was successful */ @return whether the decryption was successful */
bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn); ATTRIBUTE_COLD bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn);
/** Read the checkpoint crypto (version, msg and iv) info. /** Read the checkpoint crypto (version, msg and iv) info.
@param[in] buf checkpoint buffer @param[in] buf checkpoint buffer
@return whether the operation was successful */ @return whether the operation was successful */
UNIV_INTERN bool log_crypt_read_checkpoint_buf(const byte* buf);
bool
log_crypt_read_checkpoint_buf(const byte* buf);
/** log_crypt() operation code */ /** log_crypt() operation code */
enum log_crypt_t { enum log_crypt_t {
......
...@@ -624,7 +624,7 @@ struct log_t{ ...@@ -624,7 +624,7 @@ struct log_t{
@param[in] lsn log sequence number @param[in] lsn log sequence number
@return offset within the log */ @return offset within the log */
inline lsn_t calc_lsn_offset(lsn_t lsn) const; inline lsn_t calc_lsn_offset(lsn_t lsn) const;
lsn_t calc_lsn_offset_old(lsn_t lsn) const; inline lsn_t calc_lsn_offset_old(lsn_t lsn) const;
/** Set the field values to correspond to a given lsn. */ /** Set the field values to correspond to a given lsn. */
void set_fields(lsn_t lsn) void set_fields(lsn_t lsn)
......
/***************************************************************************** /*****************************************************************************
Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 1995, 2015, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2017, 2019, MariaDB Corporation. Copyright (c) 2017, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -187,35 +187,6 @@ log_block_convert_lsn_to_no( ...@@ -187,35 +187,6 @@ log_block_convert_lsn_to_no(
0xFUL, 0x3FFFFFFFUL)) + 1); 0xFUL, 0x3FFFFFFFUL)) + 1);
} }
/** Calculate the checksum for a log block using the pre-5.7.9 algorithm.
@param[in] block log block
@return checksum */
UNIV_INLINE
ulint
log_block_calc_checksum_format_0(
const byte* block)
{
ulint sum;
ulint sh;
ulint i;
sum = 1;
sh = 0;
for (i = 0; i < OS_FILE_LOG_BLOCK_SIZE - LOG_BLOCK_CHECKSUM; i++) {
ulint b = (ulint) block[i];
sum &= 0x7FFFFFFFUL;
sum += b;
sum += b << sh;
sh++;
if (sh > 24) {
sh = 0;
}
}
return(sum);
}
/** Calculate the CRC-32C checksum of a log block. /** Calculate the CRC-32C checksum of a log block.
@param[in] block log block @param[in] block log block
@return checksum */ @return checksum */
......
/***************************************************************************** /*****************************************************************************
Copyright (C) 2013, 2015, Google Inc. All Rights Reserved. Copyright (C) 2013, 2015, Google Inc. All Rights Reserved.
Copyright (C) 2014, 2019, MariaDB Corporation. Copyright (C) 2014, 2020, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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 the terms of the GNU General Public License as published by the Free Software
...@@ -37,22 +37,15 @@ my_bool srv_encrypt_log; ...@@ -37,22 +37,15 @@ my_bool srv_encrypt_log;
/** Redo log encryption key ID */ /** Redo log encryption key ID */
#define LOG_DEFAULT_ENCRYPTION_KEY 1 #define LOG_DEFAULT_ENCRYPTION_KEY 1
struct aes_block_t {
byte bytes[MY_AES_BLOCK_SIZE];
};
struct crypt_info_t { struct crypt_info_t {
ulint checkpoint_no; /*!< checkpoint no; 32 bits */ ulint checkpoint_no; /*!< checkpoint no; 32 bits */
uint key_version; /*!< mysqld key version */ uint key_version; /*!< mysqld key version */
/** random string for encrypting the key */ /** random string for encrypting the key */
aes_block_t crypt_msg; alignas(8) byte crypt_msg[MY_AES_BLOCK_SIZE];
/** the secret key */ /** the secret key */
aes_block_t crypt_key; alignas(8) byte crypt_key[MY_AES_BLOCK_SIZE];
/** a random string for the per-block initialization vector */ /** a random string for the per-block initialization vector */
union { alignas(4) byte crypt_nonce[4];
uint32_t word;
byte bytes[4];
} crypt_nonce;
}; };
/** The crypt info */ /** The crypt info */
...@@ -91,7 +84,7 @@ static bool init_crypt_key(crypt_info_t* info, bool upgrade = false) ...@@ -91,7 +84,7 @@ static bool init_crypt_key(crypt_info_t* info, bool upgrade = false)
byte mysqld_key[MY_AES_MAX_KEY_LENGTH]; byte mysqld_key[MY_AES_MAX_KEY_LENGTH];
uint keylen = sizeof mysqld_key; uint keylen = sizeof mysqld_key;
compile_time_assert(16 == sizeof info->crypt_key.bytes); compile_time_assert(16 == sizeof info->crypt_key);
compile_time_assert(16 == MY_AES_BLOCK_SIZE); compile_time_assert(16 == MY_AES_BLOCK_SIZE);
if (uint rc = encryption_key_get(LOG_DEFAULT_ENCRYPTION_KEY, if (uint rc = encryption_key_get(LOG_DEFAULT_ENCRYPTION_KEY,
...@@ -114,8 +107,8 @@ static bool init_crypt_key(crypt_info_t* info, bool upgrade = false) ...@@ -114,8 +107,8 @@ static bool init_crypt_key(crypt_info_t* info, bool upgrade = false)
uint dst_len; uint dst_len;
int err= my_aes_crypt(MY_AES_ECB, int err= my_aes_crypt(MY_AES_ECB,
ENCRYPTION_FLAG_NOPAD | ENCRYPTION_FLAG_ENCRYPT, ENCRYPTION_FLAG_NOPAD | ENCRYPTION_FLAG_ENCRYPT,
info->crypt_msg.bytes, MY_AES_BLOCK_SIZE, info->crypt_msg, MY_AES_BLOCK_SIZE,
info->crypt_key.bytes, &dst_len, info->crypt_key, &dst_len,
mysqld_key, keylen, NULL, 0); mysqld_key, keylen, NULL, 0);
if (err != MY_AES_OK || dst_len != MY_AES_BLOCK_SIZE) { if (err != MY_AES_OK || dst_len != MY_AES_BLOCK_SIZE) {
...@@ -139,32 +132,24 @@ bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op) ...@@ -139,32 +132,24 @@ bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op)
ut_ad(ulint(buf) % OS_FILE_LOG_BLOCK_SIZE == 0); ut_ad(ulint(buf) % OS_FILE_LOG_BLOCK_SIZE == 0);
ut_a(info.key_version); ut_a(info.key_version);
uint32_t aes_ctr_iv[MY_AES_BLOCK_SIZE / sizeof(uint32_t)]; alignas(8) byte aes_ctr_iv[MY_AES_BLOCK_SIZE];
compile_time_assert(sizeof(uint32_t) == 4);
#define LOG_CRYPT_HDR_SIZE 4 #define LOG_CRYPT_HDR_SIZE 4
lsn &= ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1); lsn &= ~lsn_t(OS_FILE_LOG_BLOCK_SIZE - 1);
for (const byte* const end = buf + size; buf != end; for (const byte* const end = buf + size; buf != end;
buf += OS_FILE_LOG_BLOCK_SIZE, lsn += OS_FILE_LOG_BLOCK_SIZE) { buf += OS_FILE_LOG_BLOCK_SIZE, lsn += OS_FILE_LOG_BLOCK_SIZE) {
uint32_t dst[(OS_FILE_LOG_BLOCK_SIZE - LOG_CRYPT_HDR_SIZE alignas(4) byte dst[OS_FILE_LOG_BLOCK_SIZE - LOG_CRYPT_HDR_SIZE
- LOG_BLOCK_CHECKSUM) - LOG_BLOCK_CHECKSUM];
/ sizeof(uint32_t)];
/* The log block number is not encrypted. */ /* The log block number is not encrypted. */
*aes_ctr_iv = memcpy_aligned<4>(dst, buf + LOG_BLOCK_HDR_NO, 4);
#ifdef WORDS_BIGENDIAN memcpy_aligned<4>(aes_ctr_iv, buf + LOG_BLOCK_HDR_NO, 4);
~LOG_BLOCK_FLUSH_BIT_MASK *aes_ctr_iv &= ~(LOG_BLOCK_FLUSH_BIT_MASK >> 24);
#else static_assert(LOG_BLOCK_HDR_NO + 4 == LOG_CRYPT_HDR_SIZE,
~(LOG_BLOCK_FLUSH_BIT_MASK >> 24) "compatibility");
#endif memcpy_aligned<4>(aes_ctr_iv + 4, info.crypt_nonce, 4);
& (*dst = *reinterpret_cast<const uint32_t*>( mach_write_to_8(my_assume_aligned<8>(aes_ctr_iv + 8), lsn);
buf + LOG_BLOCK_HDR_NO));
#if LOG_BLOCK_HDR_NO + 4 != LOG_CRYPT_HDR_SIZE
# error "LOG_BLOCK_HDR_NO has been moved; redo log format affected!"
#endif
aes_ctr_iv[1] = info.crypt_nonce.word;
mach_write_to_8(reinterpret_cast<byte*>(aes_ctr_iv + 2), lsn);
ut_ad(log_block_get_start_lsn(lsn, ut_ad(log_block_get_start_lsn(lsn,
log_block_get_hdr_no(buf)) log_block_get_hdr_no(buf))
== lsn); == lsn);
...@@ -212,9 +197,9 @@ bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op) ...@@ -212,9 +197,9 @@ bool log_crypt(byte* buf, lsn_t lsn, ulint size, log_crypt_t op)
int rc = encryption_crypt( int rc = encryption_crypt(
buf + LOG_CRYPT_HDR_SIZE, dst_size, buf + LOG_CRYPT_HDR_SIZE, dst_size,
reinterpret_cast<byte*>(dst), &dst_len, reinterpret_cast<byte*>(dst), &dst_len,
const_cast<byte*>(info.crypt_key.bytes), const_cast<byte*>(info.crypt_key),
MY_AES_BLOCK_SIZE, MY_AES_BLOCK_SIZE,
reinterpret_cast<byte*>(aes_ctr_iv), sizeof aes_ctr_iv, aes_ctr_iv, sizeof aes_ctr_iv,
op == LOG_DECRYPT op == LOG_DECRYPT
? ENCRYPTION_FLAG_DECRYPT | ENCRYPTION_FLAG_NOPAD ? ENCRYPTION_FLAG_DECRYPT | ENCRYPTION_FLAG_NOPAD
: ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD, : ENCRYPTION_FLAG_ENCRYPT | ENCRYPTION_FLAG_NOPAD,
...@@ -234,37 +219,31 @@ The random parameters will be persisted in the log checkpoint pages. ...@@ -234,37 +219,31 @@ The random parameters will be persisted in the log checkpoint pages.
@see log_crypt_write_checkpoint_buf() @see log_crypt_write_checkpoint_buf()
@see log_crypt_read_checkpoint_buf() @see log_crypt_read_checkpoint_buf()
@return whether the operation succeeded */ @return whether the operation succeeded */
UNIV_INTERN bool log_crypt_init()
bool
log_crypt_init()
{ {
info.key_version = encryption_key_get_latest_version( info.key_version=
LOG_DEFAULT_ENCRYPTION_KEY); encryption_key_get_latest_version(LOG_DEFAULT_ENCRYPTION_KEY);
if (info.key_version == ENCRYPTION_KEY_VERSION_INVALID) { if (info.key_version == ENCRYPTION_KEY_VERSION_INVALID)
ib::error() << "innodb_encrypt_log: cannot get key version"; ib::error() << "log_crypt_init(): cannot get key version";
info.key_version = 0; else if (my_random_bytes(tmp_iv, MY_AES_BLOCK_SIZE) != MY_AES_OK ||
return false; my_random_bytes(info.crypt_msg, sizeof info.crypt_msg) !=
} MY_AES_OK ||
my_random_bytes(info.crypt_nonce, sizeof info.crypt_nonce) !=
if (my_random_bytes(tmp_iv, MY_AES_BLOCK_SIZE) != MY_AES_OK MY_AES_OK)
|| my_random_bytes(info.crypt_msg.bytes, sizeof info.crypt_msg) ib::error() << "log_crypt_init(): my_random_bytes() failed";
!= MY_AES_OK else if (init_crypt_key(&info))
|| my_random_bytes(info.crypt_nonce.bytes, sizeof info.crypt_nonce) goto func_exit;
!= MY_AES_OK) {
ib::error() << "innodb_encrypt_log: my_random_bytes() failed"; info.key_version= 0;
return false; func_exit:
} return info.key_version != 0;
return init_crypt_key(&info);
} }
/** Read the MariaDB 10.1 checkpoint crypto (version, msg and iv) info. /** Read the MariaDB 10.1 checkpoint crypto (version, msg and iv) info.
@param[in] buf checkpoint buffer @param[in] buf checkpoint buffer
@return whether the operation was successful */ @return whether the operation was successful */
UNIV_INTERN ATTRIBUTE_COLD bool log_crypt_101_read_checkpoint(const byte* buf)
bool
log_crypt_101_read_checkpoint(const byte* buf)
{ {
buf += 20 + 32 * 9; buf += 20 + 32 * 9;
...@@ -286,9 +265,8 @@ log_crypt_101_read_checkpoint(const byte* buf) ...@@ -286,9 +265,8 @@ log_crypt_101_read_checkpoint(const byte* buf)
infos_used++; infos_used++;
info.checkpoint_no = checkpoint_no; info.checkpoint_no = checkpoint_no;
info.key_version = mach_read_from_4(buf + 4); info.key_version = mach_read_from_4(buf + 4);
memcpy(info.crypt_msg.bytes, buf + 8, MY_AES_BLOCK_SIZE); memcpy(info.crypt_msg, buf + 8, MY_AES_BLOCK_SIZE);
memcpy(info.crypt_nonce.bytes, buf + 24, memcpy(info.crypt_nonce, buf + 24, sizeof info.crypt_nonce);
sizeof info.crypt_nonce);
if (!init_crypt_key(&info, true)) { if (!init_crypt_key(&info, true)) {
return false; return false;
...@@ -304,10 +282,8 @@ log_crypt_101_read_checkpoint(const byte* buf) ...@@ -304,10 +282,8 @@ log_crypt_101_read_checkpoint(const byte* buf)
@param[in,out] buf log block @param[in,out] buf log block
@param[in] start_lsn server start LSN @param[in] start_lsn server start LSN
@return whether the decryption was successful */ @return whether the decryption was successful */
bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn) ATTRIBUTE_COLD bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn)
{ {
ut_ad(log_block_calc_checksum_format_0(buf)
!= log_block_get_checksum(buf));
const uint32_t checkpoint_no const uint32_t checkpoint_no
= uint32_t(log_block_get_checkpoint_no(buf)); = uint32_t(log_block_get_checkpoint_no(buf));
const crypt_info_t* info = infos; const crypt_info_t* info = infos;
...@@ -337,7 +313,7 @@ bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn) ...@@ -337,7 +313,7 @@ bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn)
/* The log block header is not encrypted. */ /* The log block header is not encrypted. */
memcpy(dst, buf, LOG_BLOCK_HDR_SIZE); memcpy(dst, buf, LOG_BLOCK_HDR_SIZE);
memcpy(aes_ctr_iv, info->crypt_nonce.bytes, 3); memcpy(aes_ctr_iv, info->crypt_nonce, 3);
mach_write_to_8(aes_ctr_iv + 3, mach_write_to_8(aes_ctr_iv + 3,
log_block_get_start_lsn(start_lsn, log_block_no)); log_block_get_start_lsn(start_lsn, log_block_no));
memcpy(aes_ctr_iv + 11, buf, 4); memcpy(aes_ctr_iv + 11, buf, 4);
...@@ -346,7 +322,7 @@ bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn) ...@@ -346,7 +322,7 @@ bool log_crypt_101_read_block(byte* buf, lsn_t start_lsn)
int rc = encryption_crypt(buf + LOG_BLOCK_HDR_SIZE, src_len, int rc = encryption_crypt(buf + LOG_BLOCK_HDR_SIZE, src_len,
dst + LOG_BLOCK_HDR_SIZE, &dst_len, dst + LOG_BLOCK_HDR_SIZE, &dst_len,
const_cast<byte*>(info->crypt_key.bytes), const_cast<byte*>(info->crypt_key),
MY_AES_BLOCK_SIZE, MY_AES_BLOCK_SIZE,
aes_ctr_iv, MY_AES_BLOCK_SIZE, aes_ctr_iv, MY_AES_BLOCK_SIZE,
ENCRYPTION_FLAG_DECRYPT ENCRYPTION_FLAG_DECRYPT
...@@ -369,15 +345,15 @@ void ...@@ -369,15 +345,15 @@ void
log_crypt_write_checkpoint_buf(byte* buf) log_crypt_write_checkpoint_buf(byte* buf)
{ {
ut_ad(info.key_version); ut_ad(info.key_version);
compile_time_assert(16 == sizeof info.crypt_msg.bytes); compile_time_assert(16 == sizeof info.crypt_msg);
compile_time_assert(16 == MY_AES_BLOCK_SIZE); compile_time_assert(16 == MY_AES_BLOCK_SIZE);
compile_time_assert(LOG_CHECKPOINT_CRYPT_MESSAGE compile_time_assert(LOG_CHECKPOINT_CRYPT_MESSAGE
- LOG_CHECKPOINT_CRYPT_NONCE - LOG_CHECKPOINT_CRYPT_NONCE
== sizeof info.crypt_nonce); == sizeof info.crypt_nonce);
memcpy(buf + LOG_CHECKPOINT_CRYPT_MESSAGE, info.crypt_msg.bytes, memcpy(buf + LOG_CHECKPOINT_CRYPT_MESSAGE, info.crypt_msg,
MY_AES_BLOCK_SIZE); MY_AES_BLOCK_SIZE);
memcpy(buf + LOG_CHECKPOINT_CRYPT_NONCE, info.crypt_nonce.bytes, memcpy(buf + LOG_CHECKPOINT_CRYPT_NONCE, info.crypt_nonce,
sizeof info.crypt_nonce); sizeof info.crypt_nonce);
mach_write_to_4(buf + LOG_CHECKPOINT_CRYPT_KEY, info.key_version); mach_write_to_4(buf + LOG_CHECKPOINT_CRYPT_KEY, info.key_version);
} }
...@@ -385,9 +361,7 @@ log_crypt_write_checkpoint_buf(byte* buf) ...@@ -385,9 +361,7 @@ log_crypt_write_checkpoint_buf(byte* buf)
/** Read the checkpoint crypto (version, msg and iv) info. /** Read the checkpoint crypto (version, msg and iv) info.
@param[in] buf checkpoint buffer @param[in] buf checkpoint buffer
@return whether the operation was successful */ @return whether the operation was successful */
UNIV_INTERN bool log_crypt_read_checkpoint_buf(const byte* buf)
bool
log_crypt_read_checkpoint_buf(const byte* buf)
{ {
info.checkpoint_no = mach_read_from_4(buf + (LOG_CHECKPOINT_NO + 4)); info.checkpoint_no = mach_read_from_4(buf + (LOG_CHECKPOINT_NO + 4));
info.key_version = mach_read_from_4(buf + LOG_CHECKPOINT_CRYPT_KEY); info.key_version = mach_read_from_4(buf + LOG_CHECKPOINT_CRYPT_KEY);
...@@ -395,15 +369,15 @@ log_crypt_read_checkpoint_buf(const byte* buf) ...@@ -395,15 +369,15 @@ log_crypt_read_checkpoint_buf(const byte* buf)
#if MY_AES_BLOCK_SIZE != 16 #if MY_AES_BLOCK_SIZE != 16
# error "MY_AES_BLOCK_SIZE != 16; redo log checkpoint format affected" # error "MY_AES_BLOCK_SIZE != 16; redo log checkpoint format affected"
#endif #endif
compile_time_assert(16 == sizeof info.crypt_msg.bytes); compile_time_assert(16 == sizeof info.crypt_msg);
compile_time_assert(16 == MY_AES_BLOCK_SIZE); compile_time_assert(16 == MY_AES_BLOCK_SIZE);
compile_time_assert(LOG_CHECKPOINT_CRYPT_MESSAGE compile_time_assert(LOG_CHECKPOINT_CRYPT_MESSAGE
- LOG_CHECKPOINT_CRYPT_NONCE - LOG_CHECKPOINT_CRYPT_NONCE
== sizeof info.crypt_nonce); == sizeof info.crypt_nonce);
memcpy(info.crypt_msg.bytes, buf + LOG_CHECKPOINT_CRYPT_MESSAGE, memcpy(info.crypt_msg, buf + LOG_CHECKPOINT_CRYPT_MESSAGE,
MY_AES_BLOCK_SIZE); MY_AES_BLOCK_SIZE);
memcpy(info.crypt_nonce.bytes, buf + LOG_CHECKPOINT_CRYPT_NONCE, memcpy(info.crypt_nonce, buf + LOG_CHECKPOINT_CRYPT_NONCE,
sizeof info.crypt_nonce); sizeof info.crypt_nonce);
return init_crypt_key(&info); return init_crypt_key(&info);
...@@ -432,7 +406,7 @@ log_tmp_block_encrypt( ...@@ -432,7 +406,7 @@ log_tmp_block_encrypt(
int rc = encryption_crypt( int rc = encryption_crypt(
src, uint(size), dst, &dst_len, src, uint(size), dst, &dst_len,
const_cast<byte*>(info.crypt_key.bytes), MY_AES_BLOCK_SIZE, const_cast<byte*>(info.crypt_key), MY_AES_BLOCK_SIZE,
reinterpret_cast<byte*>(iv), uint(sizeof iv), reinterpret_cast<byte*>(iv), uint(sizeof iv),
encrypt encrypt
? ENCRYPTION_FLAG_ENCRYPT|ENCRYPTION_FLAG_NOPAD ? ENCRYPTION_FLAG_ENCRYPT|ENCRYPTION_FLAG_NOPAD
......
...@@ -1320,15 +1320,32 @@ static bool redo_file_sizes_are_correct() ...@@ -1320,15 +1320,32 @@ static bool redo_file_sizes_are_correct()
return false; return false;
} }
/** Calculate the checksum for a log block using the pre-10.2.2 algorithm. */
inline uint32_t log_block_calc_checksum_format_0(const byte *b)
{
uint32_t sum= 1;
const byte *const end= &b[512 - 4];
for (uint32_t sh= 0; b < end; )
{
sum&= 0x7FFFFFFFUL;
sum+= uint32_t{*b} << sh++;
sum+= *b++;
if (sh > 24)
sh= 0;
}
return sum;
}
/** Determine if a redo log from before MariaDB 10.2.2 is clean. /** Determine if a redo log from before MariaDB 10.2.2 is clean.
@return error code @return error code
@retval DB_SUCCESS if the redo log is clean @retval DB_SUCCESS if the redo log is clean
@retval DB_CORRUPTION if the redo log is corrupted @retval DB_CORRUPTION if the redo log is corrupted
@retval DB_ERROR if the redo log is not empty */ @retval DB_ERROR if the redo log is not empty */
static dberr_t recv_log_recover_pre_10_2() ATTRIBUTE_COLD static dberr_t recv_log_recover_pre_10_2()
{ {
uint64_t max_no= 0; uint64_t max_no= 0;
uint64_t checkpoint_no;
byte *buf= log_sys.buf; byte *buf= log_sys.buf;
ut_ad(log_sys.log.format == 0); ut_ad(log_sys.log.format == 0);
...@@ -1364,17 +1381,17 @@ static dberr_t recv_log_recover_pre_10_2() ...@@ -1364,17 +1381,17 @@ static dberr_t recv_log_recover_pre_10_2()
continue; continue;
} }
checkpoint_no = mach_read_from_8(buf + LOG_CHECKPOINT_NO);
if (!log_crypt_101_read_checkpoint(buf)) if (!log_crypt_101_read_checkpoint(buf))
{ {
ib::error() << "Decrypting checkpoint failed"; ib::error() << "Decrypting checkpoint failed";
continue; continue;
} }
const uint64_t checkpoint_no= mach_read_from_8(buf);
DBUG_PRINT("ib_log", ("checkpoint " UINT64PF " at " LSN_PF " found", DBUG_PRINT("ib_log", ("checkpoint " UINT64PF " at " LSN_PF " found",
checkpoint_no, checkpoint_no,
mach_read_from_8(buf + LOG_CHECKPOINT_LSN))); mach_read_from_8(buf + CHECKPOINT_LSN)));
if (checkpoint_no >= max_no) if (checkpoint_no >= max_no)
{ {
...@@ -1435,10 +1452,12 @@ static dberr_t recv_log_recover_pre_10_2() ...@@ -1435,10 +1452,12 @@ static dberr_t recv_log_recover_pre_10_2()
return DB_ERROR; return DB_ERROR;
} }
/** Same as cals_lsn_offset() except that it supports multiple files */ /** Calculate the offset of a log sequence number
lsn_t log_t::file::calc_lsn_offset_old(lsn_t lsn) const in an old redo log file (during upgrade check).
@param[in] lsn log sequence number
@return byte offset within the log */
inline lsn_t log_t::file::calc_lsn_offset_old(lsn_t lsn) const
{ {
ut_ad(log_sys.mutex.is_owned() || log_write_lock_own());
const lsn_t size= capacity() * recv_sys.files_size(); const lsn_t size= capacity() * recv_sys.files_size();
lsn_t l= lsn - this->lsn; lsn_t l= lsn - this->lsn;
if (longlong(l) < 0) if (longlong(l) < 0)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment