diff --git a/src/lib/modes/xts/xts.cpp b/src/lib/modes/xts/xts.cpp index 886b7c4a18d..ce4c6e98c37 100644 --- a/src/lib/modes/xts/xts.cpp +++ b/src/lib/modes/xts/xts.cpp @@ -100,9 +100,7 @@ void XTS_Mode::update_tweak(size_t which) { const size_t blocks_in_tweak = tweak_blocks(); - for(size_t i = 1; i < blocks_in_tweak; ++i) { - poly_double_n_le(&m_tweak[i * BS], &m_tweak[(i - 1) * BS], BS); - } + xts_update_tweak_block(m_tweak.data(), BS, blocks_in_tweak); } size_t XTS_Encryption::output_length(size_t input_length) const { diff --git a/src/lib/utils/loadstor.h b/src/lib/utils/loadstor.h index 8340dd8ae2c..5e8ab5f7c7b 100644 --- a/src/lib/utils/loadstor.h +++ b/src/lib/utils/loadstor.h @@ -711,7 +711,7 @@ inline constexpr auto store_be(ParamTs&&... params) { namespace detail { template -size_t copy_out_any_word_aligned_portion(std::span& out, std::span& in) { +inline size_t copy_out_any_word_aligned_portion(std::span& out, std::span& in) { const size_t full_words = out.size() / sizeof(T); const size_t full_word_bytes = full_words * sizeof(T); const size_t remaining_bytes = out.size() - full_word_bytes; @@ -732,7 +732,7 @@ size_t copy_out_any_word_aligned_portion(std::span& out, std::span -void copy_out_be(std::span out, InR&& in) { +inline void copy_out_be(std::span out, InR&& in) { using T = std::ranges::range_value_t; std::span in_s{in}; const auto remaining_bytes = detail::copy_out_any_word_aligned_portion(out, in_s); @@ -748,7 +748,7 @@ void copy_out_be(std::span out, InR&& in) { * byte order. */ template -void copy_out_le(std::span out, InR&& in) { +inline void copy_out_le(std::span out, InR&& in) { using T = std::ranges::range_value_t; std::span in_s{in}; const auto remaining_bytes = detail::copy_out_any_word_aligned_portion(out, in_s); diff --git a/src/lib/utils/poly_dbl/poly_dbl.cpp b/src/lib/utils/poly_dbl/poly_dbl.cpp index e1d1a68e95a..e7568c2947b 100644 --- a/src/lib/utils/poly_dbl/poly_dbl.cpp +++ b/src/lib/utils/poly_dbl/poly_dbl.cpp @@ -109,4 +109,28 @@ void poly_double_n_le(uint8_t out[], const uint8_t in[], size_t n) { } } +void xts_update_tweak_block(uint8_t tweak[], size_t BS, size_t blocks_in_tweak) { + if(BS == 16) { + constexpr size_t LIMBS = 2; + + uint64_t W[LIMBS]; + load_le(W, &tweak[0], LIMBS); + + const uint64_t POLY = static_cast(MinWeightPolynomial::P128); + + for(size_t i = 1; i < blocks_in_tweak; ++i) { + const uint64_t carry = POLY * (W[1] >> 63); + W[1] = (W[1] << 1) ^ (W[0] >> 63); + W[0] = (W[0] << 1) ^ carry; + copy_out_le(std::span(&tweak[i * BS], 2 * 8), W); + } + } else { + for(size_t i = 1; i < blocks_in_tweak; ++i) { + const uint8_t* prev = &tweak[(i - 1) * BS]; + uint8_t* cur = &tweak[i * BS]; + poly_double_n_le(cur, prev, BS); + } + } +} + } // namespace Botan diff --git a/src/lib/utils/poly_dbl/poly_dbl.h b/src/lib/utils/poly_dbl/poly_dbl.h index e475b76aa1c..30bbee9ae3d 100644 --- a/src/lib/utils/poly_dbl/poly_dbl.h +++ b/src/lib/utils/poly_dbl/poly_dbl.h @@ -32,6 +32,11 @@ inline void poly_double_n(uint8_t buf[], size_t n) { */ void BOTAN_TEST_API poly_double_n_le(uint8_t out[], const uint8_t in[], size_t n); +/* +* Tweak block update step for XTS +*/ +void xts_update_tweak_block(uint8_t tweak[], size_t BS, size_t n); + } // namespace Botan #endif