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