/* * (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 #include #include #include namespace Botan { namespace PK_Ops { class Encryption_with_EME : public Encryption { public: size_t max_input_bits() const override; secure_vector 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 raw_encrypt(const uint8_t msg[], size_t len, RandomNumberGenerator& rng) = 0; std::unique_ptr m_eme; }; class Decryption_with_EME : public Decryption { public: secure_vector 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 size_t max_raw_input_bits() const = 0; virtual secure_vector raw_decrypt(const uint8_t msg[], size_t len) = 0; std::unique_ptr 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& 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 message_prefix() const { throw Exception( "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 verify_mr(const uint8_t[], size_t) { throw Invalid_State("Message recovery not supported"); } std::unique_ptr clone_emsa() const { return std::unique_ptr(m_emsa->clone()); } private: std::unique_ptr 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 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 message_prefix() const { throw Exception( "No prefix" ); } std::unique_ptr clone_emsa() const { return std::unique_ptr(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& msg, const std::vector& sig) const; virtual secure_vector raw_sign(const uint8_t msg[], size_t msg_len, RandomNumberGenerator& rng) = 0; std::unique_ptr m_emsa; const std::string m_hash; bool m_prefix_used; }; class Key_Agreement_with_KDF : public Key_Agreement { public: secure_vector 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 raw_agree(const uint8_t w[], size_t w_len) = 0; std::unique_ptr m_kdf; }; class KEM_Encryption_with_KDF : public KEM_Encryption { public: void kem_encrypt(secure_vector& out_encapsulated_key, secure_vector& 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& out_encapsulated_key, secure_vector& 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 m_kdf; }; class KEM_Decryption_with_KDF : public KEM_Decryption { public: secure_vector 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 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 m_kdf; }; } } #endif