8#include <botan/internal/pk_ops_impl.h>
10#include <botan/assert.h>
11#include <botan/hash.h>
14#include <botan/internal/ct_utils.h>
15#include <botan/internal/enc_padding.h>
16#include <botan/internal/fmt.h>
17#include <botan/internal/parsing.h>
18#include <botan/internal/scan_name.h>
20#if defined(BOTAN_HAS_RAW_HASH_FN)
21 #include <botan/internal/raw_hash.h>
27 throw Not_Implemented(
"This signature scheme does not have an algorithm identifier available");
36 return 8 * m_padding->maximum_input_size(max_ptext_input_bits());
46 const size_t written = m_padding->pad(padded_ptext, msg,
max_input_bits, rng);
47 return raw_encrypt(std::span{padded_ptext}.first(written), rng);
59 auto len = m_padding->unpad(ptext, raw);
73 ptext.resize(len.value_or(0));
86 std::span<const uint8_t> other_key,
87 std::span<const uint8_t> salt) {
88 if(!salt.empty() && m_kdf ==
nullptr) {
89 throw Invalid_Argument(
"PK_Key_Agreement::derive_key requires a KDF to use a salt");
94 return m_kdf->derive_key(key_len, z, salt.data(), salt.size());
101std::unique_ptr<HashFunction> create_signature_hash(std::string_view padding) {
108 if(req.algo_name() ==
"EMSA1" && req.arg_count() == 1) {
114#if defined(BOTAN_HAS_RAW_HASH_FN)
115 if(req.algo_name() ==
"Raw") {
116 if(req.arg_count() == 0) {
117 return std::make_unique<RawHashFunction>(
"Raw", 0);
120 if(req.arg_count() == 1) {
122 return std::make_unique<RawHashFunction>(std::move(hash));
128 throw Algorithm_Not_Found(padding);
134 Signature(), m_hash(create_signature_hash(hash)) {}
138#if defined(BOTAN_HAS_RFC6979_GENERATOR)
139std::string PK_Ops::Signature_with_Hash::rfc6979_hash_function()
const {
140 std::string hash = m_hash->name();
149 return m_hash->name();
157 const std::vector<uint8_t> msg = m_hash->final_stdvec();
158 return raw_sign(msg, rng);
162 Verification(), m_hash(create_signature_hash(padding)) {}
167 return m_hash->name();
171 std::string_view pk_algo,
172 bool allow_null_parameters) {
175 if(oid_info.size() != 2 || oid_info[0] != pk_algo) {
177 fmt(
"Unexpected AlgorithmIdentifier OID {} in association with {} key", alg_id.
oid(), pk_algo));
182 if(!allow_null_parameters) {
183 throw Decoding_Error(
fmt(
"Unexpected NULL AlgorithmIdentifier parameters for {}", pk_algo));
186 throw Decoding_Error(
fmt(
"Unexpected AlgorithmIdentifier parameters for {}", pk_algo));
198 const std::vector<uint8_t> msg = m_hash->final_stdvec();
204 return desired_shared_key_len;
211 std::span<uint8_t> out_shared_key,
213 size_t desired_shared_key_len,
214 std::span<const uint8_t> salt) {
215 BOTAN_ARG_CHECK(salt.empty() || m_kdf,
"PK_KEM_Encryptor::encrypt requires a KDF to use a salt");
220 out_shared_key.size(), desired_shared_key_len,
"KDF output length and shared key length match");
224 m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
241 return desired_shared_key_len;
248 std::span<const uint8_t> encapsulated_key,
249 size_t desired_shared_key_len,
250 std::span<const uint8_t> salt) {
251 BOTAN_ARG_CHECK(salt.empty() || m_kdf,
"PK_KEM_Decryptor::decrypt requires a KDF to use a salt");
255 out_shared_key.size(), desired_shared_key_len,
"KDF output length and shared key length match");
259 m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
#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_Padding() override
secure_vector< uint8_t > decrypt(uint8_t &valid_mask, std::span< const uint8_t > ctext) override
Decryption_with_Padding(std::string_view padding)
~Encryption_with_Padding() override
size_t max_input_bits() const override
std::vector< uint8_t > encrypt(std::span< const uint8_t > ptext, RandomNumberGenerator &rng) override
Encryption_with_Padding(std::string_view padding)
~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)
virtual void raw_kem_decrypt(std::span< uint8_t > out_raw_shared_key, std::span< const uint8_t > encapsulated_key)=0
size_t shared_key_length(size_t desired_shared_key_len) const final
virtual size_t raw_kem_shared_key_length() const =0
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
virtual size_t raw_kem_shared_key_length() const =0
size_t shared_key_length(size_t desired_shared_key_len) const final
virtual void raw_kem_encrypt(std::span< uint8_t > out_encapsulated_key, std::span< uint8_t > out_raw_shared_key, RandomNumberGenerator &rng)=0
KEM_Encryption_with_KDF(std::string_view kdf)
virtual size_t encapsulated_key_length() const =0
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
virtual void update(std::span< const uint8_t > input)=0
std::string hash_function() const final
void update(std::span< const uint8_t > input) override
~Verification_with_Hash() override
virtual bool verify(std::span< const uint8_t > msg, std::span< const uint8_t > sig)=0
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