summaryrefslogtreecommitdiff
path: root/csgo-loader/csgo-client/Security/Encryption.hpp
blob: bf1346e72f10f6598f3b4b3b0cb324dcff245c33 (plain)
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
#pragma once

#include <cstdint>
#include <vector>
#include <windows.h>
#include <wincrypt.h>

#include <UserExperience/UserInterface.hpp>

using ByteArray = std::vector<uint8_t>;

#define BLOCK_SIZE 16

namespace Wrapper
{
	// AES256 implementation.
	class Aes256
	{

	public:
		Aes256(const ByteArray& key);
		~Aes256();

		static ByteArray::size_type encrypt(const ByteArray& key, const ByteArray& plain, ByteArray& encrypted);
		static ByteArray::size_type encrypt(const ByteArray& key, const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted);
		static ByteArray::size_type decrypt(const ByteArray& key, const ByteArray& encrypted, ByteArray& plain);
		static ByteArray::size_type decrypt(const ByteArray& key, const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain);

		ByteArray::size_type encrypt_start(const ByteArray::size_type plain_length, ByteArray& encrypted);
		ByteArray::size_type encrypt_continue(const ByteArray& plain, ByteArray& encrypted);
		ByteArray::size_type encrypt_continue(const unsigned char* plain, const ByteArray::size_type plain_length, ByteArray& encrypted);
		ByteArray::size_type encrypt_end(ByteArray& encrypted);

		ByteArray::size_type decrypt_start(const ByteArray::size_type encrypted_length);
		ByteArray::size_type decrypt_continue(const ByteArray& encrypted, ByteArray& plain);
		ByteArray::size_type decrypt_continue(const unsigned char* encrypted, const ByteArray::size_type encrypted_length, ByteArray& plain);
		ByteArray::size_type decrypt_end(ByteArray& plain);

	private:
		ByteArray            m_key;
		ByteArray            m_salt;
		ByteArray            m_rkey;

		unsigned char        m_buffer[3 * BLOCK_SIZE];
		unsigned char        m_buffer_pos;
		ByteArray::size_type m_remainingLength;

		bool                 m_decryptInitialized;

		void check_and_encrypt_buffer(ByteArray& encrypted);
		void check_and_decrypt_buffer(ByteArray& plain);

		void encrypt(unsigned char *buffer);
		void decrypt(unsigned char *buffer);

		void expand_enc_key(unsigned char *rc);
		void expand_dec_key(unsigned char *rc);

		void sub_bytes(unsigned char *buffer);
		void sub_bytes_inv(unsigned char *buffer);

		void copy_key();

		void add_round_key(unsigned char *buffer, const unsigned char round);

		void shift_rows(unsigned char *buffer);
		void shift_rows_inv(unsigned char *buffer);

		void mix_columns(unsigned char *buffer);
		void mix_columns_inv(unsigned char *buffer);
	};

	// Encryption wrapper.
	class Encryption
	{
		uint8_t    m_EncryptionKey[32];
		HCRYPTPROV m_CryptProvider;

	public:
		// Generate a random cryptographic key.
		// OPTIONAL: You can pass a premade encryption key as a parameter.
		void Start();
		void Start(ByteArray &EncryptionKey);

		// Handles encryption/decryption of data.
		ByteArray Encrypt(ByteArray &Data);
		ByteArray Decrypt(ByteArray &Data);

		// Exposes the encryption key.
		ByteArray GetKey()
		{
			ByteArray TemporaryKey;

			TemporaryKey.insert(
				TemporaryKey.begin(),
				m_EncryptionKey,
				m_EncryptionKey + sizeof m_EncryptionKey
			);

			return TemporaryKey;
		}
	};
}