Cuberite
A lightweight, fast and extensible game server for Minecraft
AesCfb128Decryptor.cpp
Go to the documentation of this file.
1 
2 // AesCfb128Decryptor.cpp
3 
4 // Implements the cAesCfb128Decryptor class decrypting data using AES CFB-128
5 
6 #include "Globals.h"
7 #include "AesCfb128Decryptor.h"
8 
9 
10 
11 
12 
14  m_IsValid(false)
15 {
16 #if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
17  if (!CryptAcquireContext(&m_Aes, nullptr, nullptr, PROV_RSA_AES, CRYPT_VERIFYCONTEXT))
18  {
19  throw std::system_error(GetLastError(), std::system_category());
20  }
21 #else
22  mbedtls_aes_init(&m_Aes);
23 #endif
24 }
25 
26 
27 
28 
29 
31 {
32  // Clear the leftover in-memory data, so that they can't be accessed by a backdoor:
33 #if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
34  CryptReleaseContext(m_Aes, 0);
35 #else
36  mbedtls_aes_free(&m_Aes);
37 #endif
38 }
39 
40 
41 
42 
43 
44 void cAesCfb128Decryptor::Init(const Byte a_Key[16], const Byte a_IV[16])
45 {
46  ASSERT(!IsValid()); // Cannot Init twice
47 
48 #if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
49  struct Key
50  {
51  PUBLICKEYSTRUC Header;
52  DWORD Length;
53  Byte Key[16];
54  } Key;
55 
56  const DWORD Mode = CRYPT_MODE_CFB;
57  Key.Header = { PLAINTEXTKEYBLOB, CUR_BLOB_VERSION, 0, CALG_AES_128 };
58  Key.Length = 16;
59  std::copy_n(a_Key, 16, Key.Key);
60 
61  CryptImportKey(m_Aes, reinterpret_cast<const BYTE *>(&Key), sizeof(Key), 0, 0, &m_Key);
62  CryptSetKeyParam(m_Key, KP_MODE, reinterpret_cast<const BYTE *>(&Mode), 0);
63  CryptSetKeyParam(m_Key, KP_IV, a_IV, 0);
64 #else
65  std::copy_n(a_IV, 16, m_IV);
66  mbedtls_aes_setkey_enc(&m_Aes, a_Key, 128);
67 #endif
68 
69  m_IsValid = true;
70 }
71 
72 
73 
74 
75 
76 void cAesCfb128Decryptor::ProcessData(std::byte * const a_EncryptedIn, const size_t a_Length)
77 {
78  ASSERT(IsValid()); // Must Init() first
79 
80 #if PLATFORM_CRYPTOGRAPHY && defined(_WIN32)
81  ASSERT(a_Length <= std::numeric_limits<DWORD>::max());
82 
83  DWORD Length = static_cast<DWORD>(a_Length);
84  CryptDecrypt(m_Key, 0, FALSE, 0, reinterpret_cast<BYTE *>(a_EncryptedIn), &Length);
85 #else
86  mbedtls_aes_crypt_cfb8(&m_Aes, MBEDTLS_AES_DECRYPT, a_Length, m_IV, reinterpret_cast<unsigned char *>(a_EncryptedIn), reinterpret_cast<unsigned char *>(a_EncryptedIn));
87 #endif
88 }
#define ASSERT(x)
Definition: Globals.h:276
unsigned char Byte
Definition: Globals.h:161
Byte m_IV[16]
The InitialVector, used by the CFB mode decryption.
bool IsValid(void) const
Returns true if the object has been initialized with the Key / IV.
bool m_IsValid
Indicates whether the object has been initialized with the Key / IV.
void Init(const Byte a_Key[16], const Byte a_IV[16])
Initializes the decryptor with the specified Key / IV.
mbedtls_aes_context m_Aes
void ProcessData(std::byte *a_EncryptedIn, size_t a_Length)
Decrypts a_Length bytes of the encrypted data in-place; produces a_Length output bytes.