File: hash.hpp

package info (click to toggle)
libfilezilla 0.54.1-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 4,504 kB
  • sloc: cpp: 31,105; sh: 4,241; makefile: 375; xml: 37
file content (138 lines) | stat: -rw-r--r-- 4,813 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#ifndef LIBFILEZILLA_HASH_HEADER
#define LIBFILEZILLA_HASH_HEADER

/** \file
 * \brief Collection of cryptographic hash and MAC functions
 */

#include "libfilezilla.hpp"

#include <vector>
#include <string>

namespace fz {

/// List of supported hashing algorithms
enum class hash_algorithm
{
	md5, // insecure
	sha1, // insecure
	sha256,
	sha384,
	sha512
};

enum class hmac_algorithm
{
	sha1, // insecure
	sha256,
	sha512
};

/// Returns digest size in bytes
size_t FZ_PUBLIC_SYMBOL get_digest_size(hash_algorithm);

class buffer;

/// Accumulator for hashing large amounts of data
class FZ_PUBLIC_SYMBOL hash_accumulator final
{
public:
	/// Creates an initialized accumulator for the passed algorithm
	hash_accumulator(hash_algorithm algorithm);
	hash_accumulator(hmac_algorithm algorithm, std::vector<uint8_t> const& key);
	hash_accumulator(hmac_algorithm algorithm, std::string_view const& key);
	~hash_accumulator();

	hash_accumulator(hash_accumulator const&) = delete;
	hash_accumulator& operator=(hash_accumulator const&) = delete;

	size_t digest_size() const;

	void reinit();

	void update(std::string_view const& data);
	void update(std::basic_string_view<uint8_t> const& data);
	void update(std::vector<uint8_t> const& data);
	void update(uint8_t const* data, size_t size);
	void update(buffer const& data);
	void update(uint8_t in) {
		update(&in, 1);
	}

	/// If platform is little-endian, converts to big-endian, aka network byte order, before feeding the hash
	void update_uint32_be(uint32_t v);

	/// Also feeds length, as uint32 in network byte order, to the hash
	void update_with_length(std::string_view const& data);

	/// Returns the raw digest and reinitializes the accumulator
	std::vector<uint8_t> digest();
	void digest(uint8_t* out, size_t s);

	operator std::vector<uint8_t>() {
		return digest();
	}

	bool is_digest(std::string_view const& ref);
	bool is_digest(uint8_t const* ref, size_t s);

	template<typename T>
	hash_accumulator& operator<<(T && in) {
		update(std::forward<T>(in));
		return *this;
	}

	/// Currently only implemented for SHA1
	std::vector<std::uint8_t> export_state();
	bool import_state(std::vector<std::uint8_t> const& state);

	class impl;
private:
	impl* impl_;
};

/** \brief Standard MD5
 *
 * Insecure, avoid using this
 */
std::vector<uint8_t> FZ_PUBLIC_SYMBOL md5(std::string_view const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL md5(std::vector<uint8_t> const& data);

/// \brief Standard SHA256
std::vector<uint8_t> FZ_PUBLIC_SYMBOL sha256(std::string_view const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL sha256(std::vector<uint8_t> const& data);

/// \brief Standard SHA512
std::vector<uint8_t> FZ_PUBLIC_SYMBOL sha512(std::string_view const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL sha512(std::vector<uint8_t> const& data);

/** \brief Standard HMAC using SHA1
 *
 * While HMAC-SHA1 (as opposed to plain SHA1) is still considered secure in 2021, avoid using this for new things
 */
std::vector<uint8_t> FZ_PUBLIC_SYMBOL hmac_sha1(std::string_view const& key, std::string_view const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL hmac_sha1(std::vector<uint8_t> const& key, std::vector<uint8_t> const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL hmac_sha1(std::vector<uint8_t> const& key, std::string_view const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL hmac_sha1(std::string_view const& key, std::vector<uint8_t> const& data);

/// \brief Standard HMAC using SHA256
std::vector<uint8_t> FZ_PUBLIC_SYMBOL hmac_sha256(std::string_view const& key, std::string_view const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL hmac_sha256(std::vector<uint8_t> const& key, std::vector<uint8_t> const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL hmac_sha256(std::vector<uint8_t> const& key, std::string_view const& data);
std::vector<uint8_t> FZ_PUBLIC_SYMBOL hmac_sha256(std::string_view const& key, std::vector<uint8_t> const& data);

std::vector<uint8_t> FZ_PUBLIC_SYMBOL pbkdf2_hmac_sha256(std::basic_string_view<uint8_t> const& password, std::basic_string_view<uint8_t> const& salt, size_t length, unsigned int iterations);

template <typename PasswordContainer, typename SaltContainer,
          std::enable_if_t<sizeof(typename PasswordContainer::value_type) == sizeof(uint8_t) &&
                           sizeof(typename SaltContainer::value_type) == sizeof(uint8_t)>* = nullptr>
std::vector<uint8_t> pbkdf2_hmac_sha256(PasswordContainer const& password, SaltContainer const& salt, size_t length, unsigned int iterations)
{
	return pbkdf2_hmac_sha256(std::basic_string_view<uint8_t>(reinterpret_cast<uint8_t const*>(password.data()), password.size()),
	                          std::basic_string_view<uint8_t>(reinterpret_cast<uint8_t const*>(salt.data()), salt.size()),
	                          length, iterations);
}
}

#endif