FreeRDP
Loading...
Searching...
No Matches
winpr/libwinpr/crypto/crypto.c
1
20#include <winpr/config.h>
21#include <winpr/wlog.h>
22#include <winpr/crypto.h>
23
137#ifndef _WIN32
138
139#include "crypto.h"
140
141#include <winpr/crt.h>
142#include <winpr/collections.h>
143
144static wListDictionary* g_ProtectedMemoryBlocks = nullptr;
145
146BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
147{
148 BYTE* pCipherText = nullptr;
149 size_t cbOut = 0;
150 size_t cbFinal = 0;
151 WINPR_CIPHER_CTX* enc = nullptr;
152 BYTE randomKey[256] = WINPR_C_ARRAY_INIT;
153 WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock = nullptr;
154
155 if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS)
156 return FALSE;
157
158 if (!g_ProtectedMemoryBlocks)
159 {
160 g_ProtectedMemoryBlocks = ListDictionary_New(TRUE);
161
162 if (!g_ProtectedMemoryBlocks)
163 return FALSE;
164 }
165
166 pMemBlock = (WINPR_PROTECTED_MEMORY_BLOCK*)calloc(1, sizeof(WINPR_PROTECTED_MEMORY_BLOCK));
167
168 if (!pMemBlock)
169 return FALSE;
170
171 pMemBlock->pData = pData;
172 pMemBlock->cbData = cbData;
173 pMemBlock->dwFlags = dwFlags;
174
175 if (winpr_RAND(pMemBlock->salt, 8) < 0)
176 return FALSE;
177 if (winpr_RAND(randomKey, sizeof(randomKey)) < 0)
178 return FALSE;
179
180 if (winpr_Cipher_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, pMemBlock->salt, randomKey,
181 sizeof(randomKey), 4, pMemBlock->key, pMemBlock->iv) <= 0)
182 return FALSE;
183
184 SecureZeroMemory(randomKey, sizeof(randomKey));
185
186 cbOut = pMemBlock->cbData + 16 - 1;
187 pCipherText = (BYTE*)calloc(1, cbOut);
188
189 if (!pCipherText)
190 goto out;
191
192 if ((enc = winpr_Cipher_NewEx(WINPR_CIPHER_AES_256_CBC, WINPR_ENCRYPT, pMemBlock->key,
193 sizeof(pMemBlock->key), pMemBlock->iv, sizeof(pMemBlock->iv))) ==
194 nullptr)
195 goto out;
196 if (!winpr_Cipher_Update(enc, pMemBlock->pData, pMemBlock->cbData, pCipherText, &cbOut))
197 goto out;
198 if (!winpr_Cipher_Final(enc, pCipherText + cbOut, &cbFinal))
199 goto out;
200 winpr_Cipher_Free(enc);
201
202 CopyMemory(pMemBlock->pData, pCipherText, pMemBlock->cbData);
203 free(pCipherText);
204
205 return ListDictionary_Add(g_ProtectedMemoryBlocks, pData, pMemBlock);
206out:
207 free(pMemBlock);
208 free(pCipherText);
209 winpr_Cipher_Free(enc);
210
211 return FALSE;
212}
213
214BOOL CryptUnprotectMemory(LPVOID pData, WINPR_ATTR_UNUSED DWORD cbData, DWORD dwFlags)
215{
216 BYTE* pPlainText = nullptr;
217 size_t cbOut = 0;
218 size_t cbFinal = 0;
219 WINPR_CIPHER_CTX* dec = nullptr;
220 WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock = nullptr;
221
222 if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS)
223 return FALSE;
224
225 if (!g_ProtectedMemoryBlocks)
226 return FALSE;
227
228 pMemBlock =
229 (WINPR_PROTECTED_MEMORY_BLOCK*)ListDictionary_GetItemValue(g_ProtectedMemoryBlocks, pData);
230
231 if (!pMemBlock)
232 goto out;
233
234 cbOut = pMemBlock->cbData + 16 - 1;
235
236 pPlainText = (BYTE*)malloc(cbOut);
237
238 if (!pPlainText)
239 goto out;
240
241 if ((dec = winpr_Cipher_NewEx(WINPR_CIPHER_AES_256_CBC, WINPR_DECRYPT, pMemBlock->key,
242 sizeof(pMemBlock->key), pMemBlock->iv, sizeof(pMemBlock->iv))) ==
243 nullptr)
244 goto out;
245 if (!winpr_Cipher_Update(dec, pMemBlock->pData, pMemBlock->cbData, pPlainText, &cbOut))
246 goto out;
247 if (!winpr_Cipher_Final(dec, pPlainText + cbOut, &cbFinal))
248 goto out;
249 winpr_Cipher_Free(dec);
250
251 CopyMemory(pMemBlock->pData, pPlainText, pMemBlock->cbData);
252 SecureZeroMemory(pPlainText, pMemBlock->cbData);
253 free(pPlainText);
254
255 ListDictionary_Remove(g_ProtectedMemoryBlocks, pData);
256
257 free(pMemBlock);
258
259 return TRUE;
260
261out:
262 free(pPlainText);
263 free(pMemBlock);
264 winpr_Cipher_Free(dec);
265 return FALSE;
266}
267
268BOOL CryptProtectData(WINPR_ATTR_UNUSED DATA_BLOB* pDataIn, WINPR_ATTR_UNUSED LPCWSTR szDataDescr,
269 WINPR_ATTR_UNUSED DATA_BLOB* pOptionalEntropy,
270 WINPR_ATTR_UNUSED PVOID pvReserved,
271 WINPR_ATTR_UNUSED CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
272 WINPR_ATTR_UNUSED DWORD dwFlags, WINPR_ATTR_UNUSED DATA_BLOB* pDataOut)
273{
274 WLog_ERR("TODO", "TODO: Implement");
275 return TRUE;
276}
277
278BOOL CryptUnprotectData(WINPR_ATTR_UNUSED DATA_BLOB* pDataIn,
279 WINPR_ATTR_UNUSED LPWSTR* ppszDataDescr,
280 WINPR_ATTR_UNUSED DATA_BLOB* pOptionalEntropy,
281 WINPR_ATTR_UNUSED PVOID pvReserved,
282 WINPR_ATTR_UNUSED CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct,
283 WINPR_ATTR_UNUSED DWORD dwFlags, WINPR_ATTR_UNUSED DATA_BLOB* pDataOut)
284{
285 WLog_ERR("TODO", "TODO: Implement");
286 return TRUE;
287}
288
289BOOL CryptStringToBinaryW(WINPR_ATTR_UNUSED LPCWSTR pszString, WINPR_ATTR_UNUSED DWORD cchString,
290 WINPR_ATTR_UNUSED DWORD dwFlags, WINPR_ATTR_UNUSED BYTE* pbBinary,
291 WINPR_ATTR_UNUSED DWORD* pcbBinary, WINPR_ATTR_UNUSED DWORD* pdwSkip,
292 WINPR_ATTR_UNUSED DWORD* pdwFlags)
293{
294 WLog_ERR("TODO", "TODO: Implement");
295 return TRUE;
296}
297
298BOOL CryptStringToBinaryA(WINPR_ATTR_UNUSED LPCSTR pszString, WINPR_ATTR_UNUSED DWORD cchString,
299 WINPR_ATTR_UNUSED DWORD dwFlags, WINPR_ATTR_UNUSED BYTE* pbBinary,
300 WINPR_ATTR_UNUSED DWORD* pcbBinary, WINPR_ATTR_UNUSED DWORD* pdwSkip,
301 WINPR_ATTR_UNUSED DWORD* pdwFlags)
302{
303 WLog_ERR("TODO", "TODO: Implement");
304 return TRUE;
305}
306
307BOOL CryptBinaryToStringW(WINPR_ATTR_UNUSED CONST BYTE* pbBinary, WINPR_ATTR_UNUSED DWORD cbBinary,
308 WINPR_ATTR_UNUSED DWORD dwFlags, WINPR_ATTR_UNUSED LPWSTR pszString,
309 WINPR_ATTR_UNUSED DWORD* pcchString)
310{
311 WLog_ERR("TODO", "TODO: Implement");
312 return TRUE;
313}
314
315BOOL CryptBinaryToStringA(WINPR_ATTR_UNUSED CONST BYTE* pbBinary, WINPR_ATTR_UNUSED DWORD cbBinary,
316 WINPR_ATTR_UNUSED DWORD dwFlags, WINPR_ATTR_UNUSED LPSTR pszString,
317 WINPR_ATTR_UNUSED DWORD* pcchString)
318{
319 WLog_ERR("TODO", "TODO: Implement");
320 return TRUE;
321}
322
323#endif