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());
37 const size_t max_raw = max_ptext_input_bits();
38 const auto encoded = m_eme->encode(msg, msg_len, max_raw, rng);
39 return raw_encrypt(encoded.data(), encoded.size(), rng);
45 const uint8_t ciphertext[],
46 size_t ciphertext_len) {
48 return m_eme->unpad(valid_mask, raw.data(), raw.size());
58 size_t key_len,
const uint8_t w[],
size_t w_len,
const uint8_t salt[],
size_t salt_len) {
59 if(salt_len > 0 && m_kdf ==
nullptr) {
60 throw Invalid_Argument(
"PK_Key_Agreement::derive_key requires a KDF to use a salt");
65 return m_kdf->derive_key(key_len, z, salt, salt_len);
72std::unique_ptr<HashFunction> create_signature_hash(std::string_view padding) {
79 if(req.algo_name() ==
"EMSA1" && req.arg_count() == 1) {
85#if defined(BOTAN_HAS_RAW_HASH_FN)
86 if(req.algo_name() ==
"Raw") {
87 if(req.arg_count() == 0) {
88 return std::make_unique<RawHashFunction>(
"Raw", 0);
91 if(req.arg_count() == 1) {
93 return std::make_unique<RawHashFunction>(std::move(hash));
99 throw Algorithm_Not_Found(padding);
105 Signature(), m_hash(create_signature_hash(hash)) {}
107#if defined(BOTAN_HAS_RFC6979_GENERATOR)
108std::string PK_Ops::Signature_with_Hash::rfc6979_hash_function()
const {
109 std::string hash = m_hash->name();
118 m_hash->update(msg, msg_len);
123 return raw_sign(msg.data(), msg.size(), rng);
127 Verification(), m_hash(create_signature_hash(padding)) {}
130 std::string_view pk_algo,
131 bool allow_null_parameters) {
134 if(oid_info.size() != 2 || oid_info[0] != pk_algo) {
136 fmt(
"Unexpected AlgorithmIdentifier OID {} in association with {} key", alg_id.
oid(), pk_algo));
141 if(!allow_null_parameters) {
142 throw Decoding_Error(
fmt(
"Unexpected NULL AlgorithmIdentifier parameters for {}", pk_algo));
145 throw Decoding_Error(
fmt(
"Unexpected AlgorithmIdentifier parameters for {}", pk_algo));
153 m_hash->update(msg, msg_len);
158 return verify(msg.data(), msg.size(), sig, sig_len);
163 return desired_shared_key_len;
165 return this->raw_kem_shared_key_length();
170 std::span<uint8_t> out_shared_key,
172 size_t desired_shared_key_len,
173 std::span<const uint8_t> salt) {
174 BOTAN_ARG_CHECK(salt.empty() || m_kdf,
"PK_KEM_Encryptor::encrypt requires a KDF to use a salt");
179 out_shared_key.size(), desired_shared_key_len,
"KDF output length and shared key length match");
182 this->raw_kem_encrypt(out_encapsulated_key, raw_shared, rng);
183 m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
185 BOTAN_ASSERT_EQUAL(out_shared_key.size(), raw_kem_shared_key_length(),
"Shared key has raw KEM output length");
186 this->raw_kem_encrypt(out_encapsulated_key, out_shared_key, rng);
198 return desired_shared_key_len;
200 return this->raw_kem_shared_key_length();
205 std::span<const uint8_t> encapsulated_key,
206 size_t desired_shared_key_len,
207 std::span<const uint8_t> salt) {
208 BOTAN_ARG_CHECK(salt.empty() || m_kdf,
"PK_KEM_Decryptor::decrypt requires a KDF to use a salt");
212 out_shared_key.size(), desired_shared_key_len,
"KDF output length and shared key length match");
215 this->raw_kem_decrypt(raw_shared, encapsulated_key);
216 m_kdf->derive_key(out_shared_key, raw_shared, salt, {});
218 BOTAN_ASSERT_EQUAL(out_shared_key.size(), raw_kem_shared_key_length(),
"Shared key has raw KEM output length");
219 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 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
secure_vector< uint8_t > decrypt(uint8_t &valid_mask, const uint8_t msg[], size_t msg_len) override
Decryption_with_EME(std::string_view eme)
size_t max_input_bits() const override
secure_vector< uint8_t > encrypt(const uint8_t msg[], size_t msg_len, RandomNumberGenerator &rng) 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, const uint8_t other_key[], size_t other_key_len, const uint8_t salt[], size_t salt_len) override
secure_vector< uint8_t > sign(RandomNumberGenerator &rng) override
Signature_with_Hash(std::string_view hash)
void update(const uint8_t msg[], size_t msg_len) override
virtual AlgorithmIdentifier algorithm_identifier() const
void update(const uint8_t msg[], size_t msg_len) override
Verification_with_Hash(std::string_view hash)
bool is_valid_signature(const uint8_t sig[], size_t sig_len) 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