Skip to content

Commit

Permalink
PK_Ops::KEM_Encryption::kem_encrypt() uses std::span<> out-params
Browse files Browse the repository at this point in the history
  • Loading branch information
reneme committed Jul 3, 2023
1 parent fb4d3bf commit df38d18
Show file tree
Hide file tree
Showing 7 changed files with 53 additions and 54 deletions.
12 changes: 8 additions & 4 deletions src/lib/pubkey/kyber/kyber_common/kyber.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1092,8 +1092,8 @@ class Kyber_KEM_Encryptor final : public PK_Ops::KEM_Encryption_with_KDF,
}
}

void raw_kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
secure_vector<uint8_t>& out_shared_key,
void raw_kem_encrypt(std::span<uint8_t> out_encapsulated_key,
std::span<uint8_t> out_shared_key,
RandomNumberGenerator& rng) override {
// naming from kyber spec
auto H = mode().H();
Expand All @@ -1113,11 +1113,15 @@ class Kyber_KEM_Encryptor final : public PK_Ops::KEM_Encryption_with_KDF,
const auto lower_g_out = std::span(g_out).subspan(0, 32);
const auto upper_g_out = std::span(g_out).subspan(32, 32);

out_encapsulated_key = indcpa_enc(shared_secret, upper_g_out);
const auto encapsulation = indcpa_enc(shared_secret, upper_g_out);

// TODO: avoid copy by letting Ciphertext write straight into std::span<>
BOTAN_ASSERT_NOMSG(encapsulation.size() == out_encapsulated_key.size());
std::copy(encapsulation.begin(), encapsulation.end(), out_encapsulated_key.begin());

KDF->update(lower_g_out.data(), lower_g_out.size());
KDF->update(H->process(out_encapsulated_key));
out_shared_key = KDF->final();
KDF->final(out_shared_key);
}

private:
Expand Down
16 changes: 10 additions & 6 deletions src/lib/pubkey/mce/mceliece_key.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
#include <botan/internal/mce_internal.h>
#include <botan/internal/pk_ops_impl.h>
#include <botan/internal/polyn_gf2m.h>
#include <botan/internal/stl_util.h>

namespace Botan {

Expand Down Expand Up @@ -289,19 +290,22 @@ class MCE_KEM_Encryptor final : public PK_Ops::KEM_Encryption_with_KDF {

size_t encapsulated_key_length() const override { return (m_key.get_code_length() + 7) / 8; }

void raw_kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
secure_vector<uint8_t>& raw_shared_key,
void raw_kem_encrypt(std::span<uint8_t> out_encapsulated_key,
std::span<uint8_t> raw_shared_key,
RandomNumberGenerator& rng) override {
secure_vector<uint8_t> plaintext = m_key.random_plaintext_element(rng);

secure_vector<uint8_t> ciphertext, error_mask;
mceliece_encrypt(ciphertext, error_mask, plaintext, m_key, rng);

raw_shared_key.clear();
raw_shared_key += plaintext;
raw_shared_key += error_mask;
// TODO: Perhaps avoid the copies below
BOTAN_ASSERT_NOMSG(out_encapsulated_key.size() == ciphertext.size());
std::copy(ciphertext.begin(), ciphertext.end(), out_encapsulated_key.begin());

out_encapsulated_key.swap(ciphertext);
BOTAN_ASSERT_NOMSG(raw_shared_key.size() == plaintext.size() + error_mask.size());
BufferStuffer bs(raw_shared_key);
bs.append(plaintext);
bs.append(error_mask);
}

const McEliece_PublicKey& m_key;
Expand Down
37 changes: 16 additions & 21 deletions src/lib/pubkey/pk_ops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -166,30 +166,25 @@ size_t PK_Ops::KEM_Encryption_with_KDF::shared_key_length(size_t desired_shared_
}
}

void PK_Ops::KEM_Encryption_with_KDF::kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
secure_vector<uint8_t>& out_shared_key,
size_t desired_shared_key_len,
void PK_Ops::KEM_Encryption_with_KDF::kem_encrypt(std::span<uint8_t> out_encapsulated_key,
std::span<uint8_t> out_shared_key,
RandomNumberGenerator& rng,
const uint8_t salt[],
size_t salt_len) {
if(salt_len > 0 && m_kdf == nullptr) {
throw Invalid_Argument("PK_KEM_Encryptor::encrypt requires a KDF to use a salt");
}

secure_vector<uint8_t> raw_shared;
this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng);

BOTAN_ASSERT_EQUAL(out_encapsulated_key.size(),
this->encapsulated_key_length(),
"KEM produced encapsulated key with different length than expected");
size_t desired_shared_key_len,
std::span<const uint8_t> salt) {
BOTAN_ARG_CHECK(salt.empty() || m_kdf, "PK_KEM_Encryptor::encrypt requires a KDF to use a salt");
BOTAN_ASSERT_NOMSG(out_encapsulated_key.size() == encapsulated_key_length());

BOTAN_ASSERT_EQUAL(raw_shared.size(),
this->raw_kem_shared_key_length(),
"KEM produced shared key with different length than expected");
if(m_kdf) {
BOTAN_ASSERT_EQUAL(
out_shared_key.size(), desired_shared_key_len, "KDF output length and shared key length match");

out_shared_key = (m_kdf)
? m_kdf->derive_key(desired_shared_key_len, raw_shared.data(), raw_shared.size(), salt, salt_len)
: raw_shared;
secure_vector<uint8_t> raw_shared(raw_kem_shared_key_length());
this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng);
m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
} else {
BOTAN_ASSERT_EQUAL(out_shared_key.size(), raw_kem_shared_key_length(), "Shared key has raw KEM output length");
this->raw_kem_encrypt(out_encapsulated_key, out_shared_key, rng);
}
}

PK_Ops::KEM_Encryption_with_KDF::KEM_Encryption_with_KDF(std::string_view kdf) {
Expand Down
9 changes: 4 additions & 5 deletions src/lib/pubkey/pk_ops.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,11 @@ class Key_Agreement {
*/
class KEM_Encryption {
public:
virtual void kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
secure_vector<uint8_t>& out_shared_key,
size_t desired_shared_key_len,
virtual void kem_encrypt(std::span<uint8_t> out_encapsulated_key,
std::span<uint8_t> out_shared_key,
RandomNumberGenerator& rng,
const uint8_t salt[],
size_t salt_len) = 0;
size_t desired_shared_key_len,
std::span<const uint8_t> salt) = 0;

virtual size_t shared_key_length(size_t desired_shared_key_len) const = 0;

Expand Down
13 changes: 6 additions & 7 deletions src/lib/pubkey/pk_ops_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,18 +121,17 @@ class Key_Agreement_with_KDF : public Key_Agreement {

class KEM_Encryption_with_KDF : public KEM_Encryption {
public:
void kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
secure_vector<uint8_t>& out_shared_key,
size_t desired_shared_key_len,
void kem_encrypt(std::span<uint8_t> out_encapsulated_key,
std::span<uint8_t> out_shared_key,
RandomNumberGenerator& rng,
const uint8_t salt[],
size_t salt_len) override final;
size_t desired_shared_key_len,
std::span<const uint8_t> salt) override final;

size_t shared_key_length(size_t desired_shared_key_len) const override final;

protected:
virtual void raw_kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
secure_vector<uint8_t>& raw_shared_key,
virtual void raw_kem_encrypt(std::span<uint8_t> out_encapsulated_key,
std::span<uint8_t> raw_shared_key,
RandomNumberGenerator& rng) = 0;

virtual size_t raw_kem_shared_key_length() const = 0;
Expand Down
11 changes: 4 additions & 7 deletions src/lib/pubkey/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -148,13 +148,10 @@ void PK_KEM_Encryptor::encrypt(std::span<uint8_t> out_encapsulated_key,
RandomNumberGenerator& rng,
size_t desired_shared_key_len,
std::span<const uint8_t> salt) {
secure_vector<uint8_t> encaps;
secure_vector<uint8_t> key;
m_op->kem_encrypt(encaps, key, desired_shared_key_len, rng, salt.data(), salt.size());
BOTAN_ASSERT_EQUAL(encaps.size(), out_encapsulated_key.size(), "enough room for encapsulated key");
BOTAN_ASSERT_EQUAL(key.size(), out_shared_key.size(), "enough room for shared key");
std::copy(encaps.begin(), encaps.end(), out_encapsulated_key.begin());
std::copy(key.begin(), key.end(), out_shared_key.begin());
BOTAN_ARG_CHECK(out_encapsulated_key.size() == encapsulated_key_length(), "not enough space for encapsulated key");
BOTAN_ARG_CHECK(out_shared_key.size() == shared_key_length(desired_shared_key_len),
"not enough space for shared key");
m_op->kem_encrypt(out_encapsulated_key, out_shared_key, rng, desired_shared_key_len, salt);
}

size_t PK_KEM_Decryptor::shared_key_length(size_t desired_shared_key_len) const {
Expand Down
9 changes: 5 additions & 4 deletions src/lib/pubkey/rsa/rsa.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -686,14 +686,15 @@ class RSA_KEM_Encryption_Operation final : public PK_Ops::KEM_Encryption_with_KD

size_t encapsulated_key_length() const override { return public_modulus_bytes(); }

void raw_kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
secure_vector<uint8_t>& raw_shared_key,
void raw_kem_encrypt(std::span<uint8_t> out_encapsulated_key,
std::span<uint8_t> raw_shared_key,
RandomNumberGenerator& rng) override {
const BigInt r = BigInt::random_integer(rng, 1, get_n());
const BigInt c = public_op(r);

out_encapsulated_key = BigInt::encode_1363(c, public_modulus_bytes());
raw_shared_key = BigInt::encode_1363(r, public_modulus_bytes());
// TODO: simplify that once BigInt::encode_1363() has a std::span<> overload
BigInt::encode_1363(out_encapsulated_key.data(), out_encapsulated_key.size(), c);
BigInt::encode_1363(raw_shared_key.data(), raw_shared_key.size(), r);
}
};

Expand Down

0 comments on commit df38d18

Please sign in to comment.