8#include <botan/internal/pk_ops_impl.h>
10#include <botan/hash.h>
12#include <botan/internal/bit_ops.h>
13#include <botan/internal/fmt.h>
14#include <botan/internal/parsing.h>
15#include <botan/internal/scan_name.h>
18#if defined(BOTAN_HAS_RAW_HASH_FN)
19 #include <botan/internal/raw_hash.h>
25 throw Not_Implemented(
"This signature scheme does not have an algorithm identifier available");
31 return 8 * m_eme->maximum_input_size(max_ptext_input_bits());
35 const size_t max_raw = max_ptext_input_bits();
37 size_t written = m_eme->pad(eme_output, msg, max_raw, rng);
38 return raw_encrypt(std::span{eme_output}.first(written), rng);
47 auto len = m_eme->unpad(ptext, raw);
61 ptext.resize(len.value_or(0));
72 std::span<const uint8_t> other_key,
73 std::span<const uint8_t> salt) {
74 if(!salt.empty() && m_kdf ==
nullptr) {
75 throw Invalid_Argument(
"PK_Key_Agreement::derive_key requires a KDF to use a salt");
80 return m_kdf->derive_key(key_len, z, salt.data(), salt.size());
87std::unique_ptr<HashFunction> create_signature_hash(std::string_view padding) {
94 if(req.algo_name() ==
"EMSA1" && req.arg_count() == 1) {
100#if defined(BOTAN_HAS_RAW_HASH_FN)
101 if(req.algo_name() ==
"Raw") {
102 if(req.arg_count() == 0) {
103 return std::make_unique<RawHashFunction>(
"Raw", 0);
106 if(req.arg_count() == 1) {
108 return std::make_unique<RawHashFunction>(std::move(hash));
114 throw Algorithm_Not_Found(padding);
120 Signature(), m_hash(create_signature_hash(hash)) {}
122#if defined(BOTAN_HAS_RFC6979_GENERATOR)
123std::string PK_Ops::Signature_with_Hash::rfc6979_hash_function()
const {
124 std::string hash = m_hash->name();
137 const std::vector<uint8_t> msg = m_hash->final_stdvec();
138 return raw_sign(msg, rng);
142 Verification(), m_hash(create_signature_hash(padding)) {}
145 std::string_view pk_algo,
146 bool allow_null_parameters) {
149 if(oid_info.size() != 2 || oid_info[0] != pk_algo) {
151 fmt(
"Unexpected AlgorithmIdentifier OID {} in association with {} key", alg_id.
oid(), pk_algo));
156 if(!allow_null_parameters) {
157 throw Decoding_Error(
fmt(
"Unexpected NULL AlgorithmIdentifier parameters for {}", pk_algo));
160 throw Decoding_Error(
fmt(
"Unexpected AlgorithmIdentifier parameters for {}", pk_algo));
172 const std::vector<uint8_t> msg = m_hash->final_stdvec();
173 return verify(msg, sig);
178 return desired_shared_key_len;
180 return this->raw_kem_shared_key_length();
185 std::span<uint8_t> out_shared_key,
187 size_t desired_shared_key_len,
188 std::span<const uint8_t> salt) {
189 BOTAN_ARG_CHECK(salt.empty() || m_kdf,
"PK_KEM_Encryptor::encrypt requires a KDF to use a salt");
194 out_shared_key.size(), desired_shared_key_len,
"KDF output length and shared key length match");
197 this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng);
198 m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
200 BOTAN_ASSERT_EQUAL(out_shared_key.size(), raw_kem_shared_key_length(),
"Shared key has raw KEM output length");
201 this->raw_kem_encrypt(out_encapsulated_key, out_shared_key, rng);
213 return desired_shared_key_len;
215 return this->raw_kem_shared_key_length();
220 std::span<const uint8_t> encapsulated_key,
221 size_t desired_shared_key_len,
222 std::span<const uint8_t> salt) {
223 BOTAN_ARG_CHECK(salt.empty() || m_kdf,
"PK_KEM_Decryptor::decrypt requires a KDF to use a salt");
227 out_shared_key.size(), desired_shared_key_len,
"KDF output length and shared key length match");
230 this->raw_kem_decrypt(raw_shared, encapsulated_key);
231 m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
233 BOTAN_ASSERT_EQUAL(out_shared_key.size(), raw_kem_shared_key_length(),
"Shared key has raw KEM output length");
234 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)
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(std::string_view eme)
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
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)
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
void update(std::span< const uint8_t > input) override
Signature_with_Hash(std::string_view hash)
virtual AlgorithmIdentifier algorithm_identifier() const
void update(std::span< const uint8_t > input) 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