8#include <botan/internal/pk_ops_impl.h>
10#include <botan/hash.h>
13#include <botan/internal/bit_ops.h>
14#include <botan/internal/eme.h>
15#include <botan/internal/fmt.h>
16#include <botan/internal/parsing.h>
17#include <botan/internal/scan_name.h>
19#if defined(BOTAN_HAS_RAW_HASH_FN)
20 #include <botan/internal/raw_hash.h>
26 throw Not_Implemented(
"This signature scheme does not have an algorithm identifier available");
34 return 8 * m_eme->maximum_input_size(max_ptext_input_bits());
38 const size_t max_input_bits = max_ptext_input_bits();
39 const size_t max_input_bytes = (max_input_bits + 7) / 8;
43 const size_t written = m_eme->pad(eme_output, msg, max_input_bits, rng);
44 return raw_encrypt(std::span{eme_output}.first(written), rng);
55 auto len = m_eme->unpad(ptext, raw);
69 ptext.resize(len.value_or(0));
82 std::span<const uint8_t> other_key,
83 std::span<const uint8_t> salt) {
84 if(!salt.empty() && m_kdf ==
nullptr) {
85 throw Invalid_Argument(
"PK_Key_Agreement::derive_key requires a KDF to use a salt");
90 return m_kdf->derive_key(key_len, z, salt.data(), salt.size());
97std::unique_ptr<HashFunction> create_signature_hash(std::string_view padding) {
104 if(req.algo_name() ==
"EMSA1" && req.arg_count() == 1) {
110#if defined(BOTAN_HAS_RAW_HASH_FN)
111 if(req.algo_name() ==
"Raw") {
112 if(req.arg_count() == 0) {
113 return std::make_unique<RawHashFunction>(
"Raw", 0);
116 if(req.arg_count() == 1) {
118 return std::make_unique<RawHashFunction>(std::move(hash));
124 throw Algorithm_Not_Found(padding);
130 Signature(), m_hash(create_signature_hash(hash)) {}
134#if defined(BOTAN_HAS_RFC6979_GENERATOR)
135std::string PK_Ops::Signature_with_Hash::rfc6979_hash_function()
const {
136 std::string hash = m_hash->name();
145 return m_hash->name();
153 const std::vector<uint8_t> msg = m_hash->final_stdvec();
154 return raw_sign(msg, rng);
158 Verification(), m_hash(create_signature_hash(padding)) {}
163 return m_hash->name();
167 std::string_view pk_algo,
168 bool allow_null_parameters) {
171 if(oid_info.size() != 2 || oid_info[0] != pk_algo) {
173 fmt(
"Unexpected AlgorithmIdentifier OID {} in association with {} key", alg_id.
oid(), pk_algo));
178 if(!allow_null_parameters) {
179 throw Decoding_Error(
fmt(
"Unexpected NULL AlgorithmIdentifier parameters for {}", pk_algo));
182 throw Decoding_Error(
fmt(
"Unexpected AlgorithmIdentifier parameters for {}", pk_algo));
194 const std::vector<uint8_t> msg = m_hash->final_stdvec();
195 return verify(msg, sig);
200 return desired_shared_key_len;
202 return this->raw_kem_shared_key_length();
207 std::span<uint8_t> out_shared_key,
209 size_t desired_shared_key_len,
210 std::span<const uint8_t> salt) {
211 BOTAN_ARG_CHECK(salt.empty() || m_kdf,
"PK_KEM_Encryptor::encrypt requires a KDF to use a salt");
216 out_shared_key.size(), desired_shared_key_len,
"KDF output length and shared key length match");
219 this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng);
220 m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
222 BOTAN_ASSERT_EQUAL(out_shared_key.size(), raw_kem_shared_key_length(),
"Shared key has raw KEM output length");
223 this->raw_kem_encrypt(out_encapsulated_key, out_shared_key, rng);
237 return desired_shared_key_len;
239 return this->raw_kem_shared_key_length();
244 std::span<const uint8_t> encapsulated_key,
245 size_t desired_shared_key_len,
246 std::span<const uint8_t> salt) {
247 BOTAN_ARG_CHECK(salt.empty() || m_kdf,
"PK_KEM_Decryptor::decrypt requires a KDF to use a salt");
251 out_shared_key.size(), desired_shared_key_len,
"KDF output length and shared key length match");
254 this->raw_kem_decrypt(raw_shared, encapsulated_key);
255 m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
257 BOTAN_ASSERT_EQUAL(out_shared_key.size(), raw_kem_shared_key_length(),
"Shared key has raw KEM output length");
258 this->raw_kem_decrypt(out_shared_key, encapsulated_key);
#define BOTAN_ASSERT_NOMSG(expr)
#define BOTAN_ASSERT_EQUAL(expr1, expr2, assertion_made)
#define BOTAN_ARG_CHECK(expr, msg)
bool parameters_are_empty() const
bool parameters_are_null() const
static constexpr Mask< T > from_choice(Choice c)
static std::unique_ptr< HashFunction > create_or_throw(std::string_view algo_spec, std::string_view provider="")
static std::unique_ptr< HashFunction > create(std::string_view algo_spec, std::string_view provider="")
static std::unique_ptr< KDF > create_or_throw(std::string_view algo_spec, std::string_view provider="")
std::string to_formatted_string() const
Decryption_with_EME(std::string_view eme)
~Decryption_with_EME() override
secure_vector< uint8_t > decrypt(uint8_t &valid_mask, std::span< const uint8_t > ctext) override
std::vector< uint8_t > encrypt(std::span< const uint8_t > ptext, RandomNumberGenerator &rng) override
size_t max_input_bits() const override
~Encryption_with_EME() override
Encryption_with_EME(std::string_view eme)
~KEM_Decryption_with_KDF() override
void kem_decrypt(std::span< uint8_t > out_shared_key, std::span< const uint8_t > encapsulated_key, size_t desired_shared_key_len, std::span< const uint8_t > salt) final
KEM_Decryption_with_KDF(std::string_view kdf)
size_t shared_key_length(size_t desired_shared_key_len) const final
void kem_encrypt(std::span< uint8_t > out_encapsulated_key, std::span< uint8_t > out_shared_key, RandomNumberGenerator &rng, size_t desired_shared_key_len, std::span< const uint8_t > salt) final
~KEM_Encryption_with_KDF() override
size_t shared_key_length(size_t desired_shared_key_len) const final
KEM_Encryption_with_KDF(std::string_view kdf)
Key_Agreement_with_KDF(std::string_view kdf)
~Key_Agreement_with_KDF() override
secure_vector< uint8_t > agree(size_t key_len, std::span< const uint8_t > other_key, std::span< const uint8_t > salt) override
std::vector< uint8_t > sign(RandomNumberGenerator &rng) override
std::string hash_function() const final
~Signature_with_Hash() override
void update(std::span< const uint8_t > input) override
Signature_with_Hash(std::string_view hash)
virtual AlgorithmIdentifier algorithm_identifier() const
std::string hash_function() const final
void update(std::span< const uint8_t > input) override
~Verification_with_Hash() override
Verification_with_Hash(std::string_view hash)
bool is_valid_signature(std::span< const uint8_t > sig) override
std::string fmt(std::string_view format, const T &... args)
std::vector< std::string > split_on(std::string_view str, char delim)
std::vector< T, secure_allocator< T > > secure_vector