Revision control
Copy as Markdown
Other Tools
/*
* (C) 2015 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
#ifndef BOTAN_PK_OPERATION_IMPL_H_
#define BOTAN_PK_OPERATION_IMPL_H_
#include <botan/pk_ops.h>
#include <botan/eme.h>
#include <botan/kdf.h>
#include <botan/emsa.h>
namespace Botan {
namespace PK_Ops {
class Encryption_with_EME : public Encryption
{
public:
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() = default;
protected:
explicit Encryption_with_EME(const std::string& eme);
private:
virtual size_t max_raw_input_bits() const = 0;
virtual secure_vector<uint8_t> raw_encrypt(const uint8_t msg[], size_t len,
RandomNumberGenerator& rng) = 0;
std::unique_ptr<EME> m_eme;
};
class Decryption_with_EME : public Decryption
{
public:
secure_vector<uint8_t> decrypt(uint8_t& valid_mask,
const uint8_t msg[], size_t msg_len) override;
~Decryption_with_EME() = default;
protected:
explicit Decryption_with_EME(const std::string& eme);
private:
virtual secure_vector<uint8_t> raw_decrypt(const uint8_t msg[], size_t len) = 0;
std::unique_ptr<EME> m_eme;
};
class Verification_with_EMSA : public Verification
{
public:
~Verification_with_EMSA() = default;
void update(const uint8_t msg[], size_t msg_len) override;
bool is_valid_signature(const uint8_t sig[], size_t sig_len) override;
bool do_check(const secure_vector<uint8_t>& msg,
const uint8_t sig[], size_t sig_len);
std::string hash_for_signature() { return m_hash; }
protected:
explicit Verification_with_EMSA(const std::string& emsa);
/**
* Get the maximum message size in bits supported by this public key.
* @return maximum message in bits
*/
virtual size_t max_input_bits() const = 0;
/**
* @return boolean specifying if this signature scheme uses
* a message prefix returned by message_prefix()
*/
virtual bool has_prefix() { return false; }
/**
* @return the message prefix if this signature scheme uses
* a message prefix, signaled via has_prefix()
*/
virtual secure_vector<uint8_t> message_prefix() const { throw Invalid_State("No prefix"); }
/**
* @return boolean specifying if this key type supports message
* recovery and thus if you need to call verify() or verify_mr()
*/
virtual bool with_recovery() const = 0;
/*
* Perform a signature check operation
* @param msg the message
* @param msg_len the length of msg in bytes
* @param sig the signature
* @param sig_len the length of sig in bytes
* @returns if signature is a valid one for message
*/
virtual bool verify(const uint8_t[], size_t,
const uint8_t[], size_t)
{
throw Invalid_State("Message recovery required");
}
/*
* Perform a signature operation (with message recovery)
* Only call this if with_recovery() returns true
* @param msg the message
* @param msg_len the length of msg in bytes
* @returns recovered message
*/
virtual secure_vector<uint8_t> verify_mr(const uint8_t[], size_t)
{
throw Invalid_State("Message recovery not supported");
}
std::unique_ptr<EMSA> clone_emsa() const { return std::unique_ptr<EMSA>(m_emsa->clone()); }
private:
std::unique_ptr<EMSA> m_emsa;
const std::string m_hash;
bool m_prefix_used;
};
class Signature_with_EMSA : public Signature
{
public:
void update(const uint8_t msg[], size_t msg_len) override;
secure_vector<uint8_t> sign(RandomNumberGenerator& rng) override;
protected:
explicit Signature_with_EMSA(const std::string& emsa);
~Signature_with_EMSA() = default;
std::string hash_for_signature() { return m_hash; }
/**
* @return boolean specifying if this signature scheme uses
* a message prefix returned by message_prefix()
*/
virtual bool has_prefix() { return false; }
/**
* @return the message prefix if this signature scheme uses
* a message prefix, signaled via has_prefix()
*/
virtual secure_vector<uint8_t> message_prefix() const { throw Invalid_State("No prefix"); }
std::unique_ptr<EMSA> clone_emsa() const { return std::unique_ptr<EMSA>(m_emsa->clone()); }
private:
/**
* Get the maximum message size in bits supported by this public key.
* @return maximum message in bits
*/
virtual size_t max_input_bits() const = 0;
bool self_test_signature(const std::vector<uint8_t>& msg,
const std::vector<uint8_t>& sig) const;
virtual secure_vector<uint8_t> raw_sign(const uint8_t msg[], size_t msg_len,
RandomNumberGenerator& rng) = 0;
std::unique_ptr<EMSA> m_emsa;
const std::string m_hash;
bool m_prefix_used;
};
class Key_Agreement_with_KDF : public Key_Agreement
{
public:
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;
protected:
explicit Key_Agreement_with_KDF(const std::string& kdf);
~Key_Agreement_with_KDF() = default;
private:
virtual secure_vector<uint8_t> raw_agree(const uint8_t w[], size_t w_len) = 0;
std::unique_ptr<KDF> m_kdf;
};
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,
Botan::RandomNumberGenerator& rng,
const uint8_t salt[],
size_t salt_len) override;
protected:
virtual void raw_kem_encrypt(secure_vector<uint8_t>& out_encapsulated_key,
secure_vector<uint8_t>& raw_shared_key,
Botan::RandomNumberGenerator& rng) = 0;
explicit KEM_Encryption_with_KDF(const std::string& kdf);
~KEM_Encryption_with_KDF() = default;
private:
std::unique_ptr<KDF> m_kdf;
};
class KEM_Decryption_with_KDF : public KEM_Decryption
{
public:
secure_vector<uint8_t> kem_decrypt(const uint8_t encap_key[],
size_t len,
size_t desired_shared_key_len,
const uint8_t salt[],
size_t salt_len) override;
protected:
virtual secure_vector<uint8_t>
raw_kem_decrypt(const uint8_t encap_key[], size_t len) = 0;
explicit KEM_Decryption_with_KDF(const std::string& kdf);
~KEM_Decryption_with_KDF() = default;
private:
std::unique_ptr<KDF> m_kdf;
};
}
}
#endif