Skip to content

Commit

Permalink
Use std::span in Block_Cipher encrypt/decrypt methods
Browse files Browse the repository at this point in the history
This demotes Block_Cipher::encrypt_n/decrypt_n to top-level methods
and introduces new (private) virtual methods (encrypt/decrypt_blocks)
that use std::span for the in/out buffers. Also, this adapts all block
cipher implementations in the library to use the new API.
  • Loading branch information
reneme committed Mar 25, 2024
1 parent 38a0b56 commit e5ead5f
Show file tree
Hide file tree
Showing 40 changed files with 500 additions and 499 deletions.
62 changes: 34 additions & 28 deletions src/lib/block/aes/aes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -501,7 +501,10 @@ void inv_mix_columns(uint32_t B[8]) {
/*
* AES Encryption
*/
void aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secure_vector<uint32_t>& EK) {
void aes_encrypt_n(std::span<const uint8_t> in,
std::span<uint8_t> out,
size_t blocks,
const secure_vector<uint32_t>& EK) {
BOTAN_ASSERT(EK.size() == 44 || EK.size() == 52 || EK.size() == 60, "Key was set");

const size_t rounds = (EK.size() - 4) / 4;
Expand All @@ -519,7 +522,7 @@ void aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secur

uint32_t B[8] = {0};

load_be(B, in, this_loop * 4);
load_be(B, in.data(), this_loop * 4);

CT::poison(B, 8);

Expand Down Expand Up @@ -550,18 +553,21 @@ void aes_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secur

CT::unpoison(B, 8);

copy_out_be(std::span(out, this_loop * 4 * sizeof(uint32_t)), B);
copy_out_be(out.first(this_loop * BLOCK_SIZE), B);

in += this_loop * BLOCK_SIZE;
out += this_loop * BLOCK_SIZE;
in = in.subspan(this_loop * BLOCK_SIZE);
out = out.subspan(this_loop * BLOCK_SIZE);
blocks -= this_loop;
}
}

/*
* AES Decryption
*/
void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secure_vector<uint32_t>& DK) {
void aes_decrypt_n(std::span<const uint8_t> in,
std::span<uint8_t> out,
size_t blocks,
const secure_vector<uint32_t>& DK) {
BOTAN_ASSERT(DK.size() == 44 || DK.size() == 52 || DK.size() == 60, "Key was set");

const size_t rounds = (DK.size() - 4) / 4;
Expand All @@ -581,7 +587,7 @@ void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secur

CT::poison(B, 8);

load_be(B, in, this_loop * 4);
load_be(B, in.data(), this_loop * 4);

for(size_t i = 0; i != 8; ++i) {
B[i] ^= DK[i % 4];
Expand Down Expand Up @@ -610,10 +616,10 @@ void aes_decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks, const secur

CT::unpoison(B, 8);

copy_out_be(std::span(out, this_loop * 4 * sizeof(uint32_t)), B);
copy_out_be(out.first(this_loop * BLOCK_SIZE), B);

in += this_loop * BLOCK_SIZE;
out += this_loop * BLOCK_SIZE;
in = in.subspan(this_loop * BLOCK_SIZE);
out = out.subspan(this_loop * BLOCK_SIZE);
blocks -= this_loop;
}
}
Expand Down Expand Up @@ -809,36 +815,36 @@ bool AES_256::has_keying_material() const {
return !m_EK.empty();
}

void AES_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void AES_128::encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();

#if defined(BOTAN_HAS_HW_AES_SUPPORT)
if(CPUID::has_hw_aes()) {
return hw_aes_encrypt_n(in, out, blocks);
return hw_aes_encrypt_n(in.data(), out.data(), blocks);
}
#endif

#if defined(BOTAN_HAS_AES_VPERM)
if(CPUID::has_vperm()) {
return vperm_encrypt_n(in, out, blocks);
return vperm_encrypt_n(in.data(), out.data(), blocks);
}
#endif

aes_encrypt_n(in, out, blocks, m_EK);
}

void AES_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void AES_128::decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();

#if defined(BOTAN_HAS_HW_AES_SUPPORT)
if(CPUID::has_hw_aes()) {
return hw_aes_decrypt_n(in, out, blocks);
return hw_aes_decrypt_n(in.data(), out.data(), blocks);
}
#endif

#if defined(BOTAN_HAS_AES_VPERM)
if(CPUID::has_vperm()) {
return vperm_decrypt_n(in, out, blocks);
return vperm_decrypt_n(in.data(), out.data(), blocks);
}
#endif

Expand Down Expand Up @@ -872,36 +878,36 @@ void AES_128::clear() {
zap(m_DK);
}

void AES_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void AES_192::encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();

#if defined(BOTAN_HAS_HW_AES_SUPPORT)
if(CPUID::has_hw_aes()) {
return hw_aes_encrypt_n(in, out, blocks);
return hw_aes_encrypt_n(in.data(), out.data(), blocks);
}
#endif

#if defined(BOTAN_HAS_AES_VPERM)
if(CPUID::has_vperm()) {
return vperm_encrypt_n(in, out, blocks);
return vperm_encrypt_n(in.data(), out.data(), blocks);
}
#endif

aes_encrypt_n(in, out, blocks, m_EK);
}

void AES_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void AES_192::decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();

#if defined(BOTAN_HAS_HW_AES_SUPPORT)
if(CPUID::has_hw_aes()) {
return hw_aes_decrypt_n(in, out, blocks);
return hw_aes_decrypt_n(in.data(), out.data(), blocks);
}
#endif

#if defined(BOTAN_HAS_AES_VPERM)
if(CPUID::has_vperm()) {
return vperm_decrypt_n(in, out, blocks);
return vperm_decrypt_n(in.data(), out.data(), blocks);
}
#endif

Expand Down Expand Up @@ -935,36 +941,36 @@ void AES_192::clear() {
zap(m_DK);
}

void AES_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void AES_256::encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();

#if defined(BOTAN_HAS_HW_AES_SUPPORT)
if(CPUID::has_hw_aes()) {
return hw_aes_encrypt_n(in, out, blocks);
return hw_aes_encrypt_n(in.data(), out.data(), blocks);
}
#endif

#if defined(BOTAN_HAS_AES_VPERM)
if(CPUID::has_vperm()) {
return vperm_encrypt_n(in, out, blocks);
return vperm_encrypt_n(in.data(), out.data(), blocks);
}
#endif

aes_encrypt_n(in, out, blocks, m_EK);
}

void AES_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void AES_256::decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();

#if defined(BOTAN_HAS_HW_AES_SUPPORT)
if(CPUID::has_hw_aes()) {
return hw_aes_decrypt_n(in, out, blocks);
return hw_aes_decrypt_n(in.data(), out.data(), blocks);
}
#endif

#if defined(BOTAN_HAS_AES_VPERM)
if(CPUID::has_vperm()) {
return vperm_decrypt_n(in, out, blocks);
return vperm_decrypt_n(in.data(), out.data(), blocks);
}
#endif

Expand Down
15 changes: 6 additions & 9 deletions src/lib/block/aes/aes.h
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,6 @@ namespace Botan {
*/
class AES_128 final : public Block_Cipher_Fixed_Params<16, 16> {
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;

void clear() override;

std::string provider() const override;
Expand All @@ -34,6 +31,8 @@ class AES_128 final : public Block_Cipher_Fixed_Params<16, 16> {

private:
void key_schedule(std::span<const uint8_t> key) override;
void encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;
void decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;

#if defined(BOTAN_HAS_AES_VPERM)
void vperm_encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const;
Expand All @@ -58,9 +57,6 @@ class AES_128 final : public Block_Cipher_Fixed_Params<16, 16> {
*/
class AES_192 final : public Block_Cipher_Fixed_Params<16, 24> {
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;

void clear() override;

std::string provider() const override;
Expand Down Expand Up @@ -89,6 +85,8 @@ class AES_192 final : public Block_Cipher_Fixed_Params<16, 24> {
#endif

void key_schedule(std::span<const uint8_t> key) override;
void encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;
void decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;

secure_vector<uint32_t> m_EK, m_DK;
};
Expand All @@ -98,9 +96,6 @@ class AES_192 final : public Block_Cipher_Fixed_Params<16, 24> {
*/
class AES_256 final : public Block_Cipher_Fixed_Params<16, 32> {
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;

void clear() override;

std::string provider() const override;
Expand Down Expand Up @@ -129,6 +124,8 @@ class AES_256 final : public Block_Cipher_Fixed_Params<16, 32> {
#endif

void key_schedule(std::span<const uint8_t> key) override;
void encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;
void decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;

secure_vector<uint32_t> m_EK, m_DK;
};
Expand Down
16 changes: 8 additions & 8 deletions src/lib/block/aria/aria.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,14 +163,14 @@ inline void ARIA_FE(uint32_t& T0, uint32_t& T1, uint32_t& T2, uint32_t& T3) {
/*
* ARIA encryption and decryption
*/
void transform(const uint8_t in[], uint8_t out[], size_t blocks, const secure_vector<uint32_t>& KS) {
void transform(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks, const secure_vector<uint32_t>& KS) {
prefetch_arrays(S1, S2, X1, X2);

const size_t ROUNDS = (KS.size() / 4) - 1;

for(size_t i = 0; i != blocks; ++i) {
uint32_t t0, t1, t2, t3;
load_be(in + 16 * i, t0, t1, t2, t3);
load_be(in.subspan(16 * i).first<16>(), t0, t1, t2, t3);

for(size_t r = 0; r < ROUNDS; r += 2) {
t0 ^= KS[4 * r];
Expand Down Expand Up @@ -359,32 +359,32 @@ void key_schedule(secure_vector<uint32_t>& ERK, secure_vector<uint32_t>& DRK, st

} // namespace

void ARIA_128::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void ARIA_128::encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();
ARIA_F::transform(in, out, blocks, m_ERK);
}

void ARIA_192::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void ARIA_192::encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();
ARIA_F::transform(in, out, blocks, m_ERK);
}

void ARIA_256::encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void ARIA_256::encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();
ARIA_F::transform(in, out, blocks, m_ERK);
}

void ARIA_128::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void ARIA_128::decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();
ARIA_F::transform(in, out, blocks, m_DRK);
}

void ARIA_192::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void ARIA_192::decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();
ARIA_F::transform(in, out, blocks, m_DRK);
}

void ARIA_256::decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const {
void ARIA_256::decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const {
assert_key_material_set();
ARIA_F::transform(in, out, blocks, m_DRK);
}
Expand Down
15 changes: 6 additions & 9 deletions src/lib/block/aria/aria.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,6 @@ namespace Botan {
*/
class ARIA_128 final : public Block_Cipher_Fixed_Params<16, 16> {
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;

void clear() override;

std::string name() const override { return "ARIA-128"; }
Expand All @@ -38,6 +35,8 @@ class ARIA_128 final : public Block_Cipher_Fixed_Params<16, 16> {

private:
void key_schedule(std::span<const uint8_t> key) override;
void encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;
void decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;

// Encryption and Decryption round keys.
secure_vector<uint32_t> m_ERK, m_DRK;
Expand All @@ -48,9 +47,6 @@ class ARIA_128 final : public Block_Cipher_Fixed_Params<16, 16> {
*/
class ARIA_192 final : public Block_Cipher_Fixed_Params<16, 24> {
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;

void clear() override;

std::string name() const override { return "ARIA-192"; }
Expand All @@ -61,6 +57,8 @@ class ARIA_192 final : public Block_Cipher_Fixed_Params<16, 24> {

private:
void key_schedule(std::span<const uint8_t> key) override;
void encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;
void decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;

// Encryption and Decryption round keys.
secure_vector<uint32_t> m_ERK, m_DRK;
Expand All @@ -71,9 +69,6 @@ class ARIA_192 final : public Block_Cipher_Fixed_Params<16, 24> {
*/
class ARIA_256 final : public Block_Cipher_Fixed_Params<16, 32> {
public:
void encrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;
void decrypt_n(const uint8_t in[], uint8_t out[], size_t blocks) const override;

void clear() override;

std::string name() const override { return "ARIA-256"; }
Expand All @@ -84,6 +79,8 @@ class ARIA_256 final : public Block_Cipher_Fixed_Params<16, 32> {

private:
void key_schedule(std::span<const uint8_t> key) override;
void encrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;
void decrypt_blocks(std::span<const uint8_t> in, std::span<uint8_t> out, size_t blocks) const override;

// Encryption and Decryption round keys.
secure_vector<uint32_t> m_ERK, m_DRK;
Expand Down
Loading

0 comments on commit e5ead5f

Please sign in to comment.