FreeRDP
winpr/libwinpr/crypto/crypto.c
1 
20 #include <winpr/config.h>
21 
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 
144 static wListDictionary* g_ProtectedMemoryBlocks = NULL;
145 
146 BOOL CryptProtectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
147 {
148  BYTE* pCipherText = NULL;
149  size_t cbOut = 0;
150  size_t cbFinal = 0;
151  WINPR_CIPHER_CTX* enc = NULL;
152  BYTE randomKey[256] = { 0 };
153  WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock = NULL;
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  winpr_RAND(pMemBlock->salt, 8);
176  winpr_RAND(randomKey, sizeof(randomKey));
177 
178  winpr_Cipher_BytesToKey(WINPR_CIPHER_AES_256_CBC, WINPR_MD_SHA1, pMemBlock->salt, randomKey,
179  sizeof(randomKey), 4, pMemBlock->key, pMemBlock->iv);
180 
181  SecureZeroMemory(randomKey, sizeof(randomKey));
182 
183  cbOut = pMemBlock->cbData + 16 - 1;
184  pCipherText = (BYTE*)calloc(1, cbOut);
185 
186  if (!pCipherText)
187  goto out;
188 
189  if ((enc = winpr_Cipher_NewEx(WINPR_CIPHER_AES_256_CBC, WINPR_ENCRYPT, pMemBlock->key,
190  sizeof(pMemBlock->key), pMemBlock->iv, sizeof(pMemBlock->iv))) ==
191  NULL)
192  goto out;
193  if (!winpr_Cipher_Update(enc, pMemBlock->pData, pMemBlock->cbData, pCipherText, &cbOut))
194  goto out;
195  if (!winpr_Cipher_Final(enc, pCipherText + cbOut, &cbFinal))
196  goto out;
197  winpr_Cipher_Free(enc);
198 
199  CopyMemory(pMemBlock->pData, pCipherText, pMemBlock->cbData);
200  free(pCipherText);
201 
202  return ListDictionary_Add(g_ProtectedMemoryBlocks, pData, pMemBlock);
203 out:
204  free(pMemBlock);
205  free(pCipherText);
206  winpr_Cipher_Free(enc);
207 
208  return FALSE;
209 }
210 
211 BOOL CryptUnprotectMemory(LPVOID pData, DWORD cbData, DWORD dwFlags)
212 {
213  BYTE* pPlainText = NULL;
214  size_t cbOut = 0;
215  size_t cbFinal = 0;
216  WINPR_CIPHER_CTX* dec = NULL;
217  WINPR_PROTECTED_MEMORY_BLOCK* pMemBlock = NULL;
218 
219  if (dwFlags != CRYPTPROTECTMEMORY_SAME_PROCESS)
220  return FALSE;
221 
222  if (!g_ProtectedMemoryBlocks)
223  return FALSE;
224 
225  pMemBlock =
226  (WINPR_PROTECTED_MEMORY_BLOCK*)ListDictionary_GetItemValue(g_ProtectedMemoryBlocks, pData);
227 
228  if (!pMemBlock)
229  goto out;
230 
231  cbOut = pMemBlock->cbData + 16 - 1;
232 
233  pPlainText = (BYTE*)malloc(cbOut);
234 
235  if (!pPlainText)
236  goto out;
237 
238  if ((dec = winpr_Cipher_NewEx(WINPR_CIPHER_AES_256_CBC, WINPR_DECRYPT, pMemBlock->key,
239  sizeof(pMemBlock->key), pMemBlock->iv, sizeof(pMemBlock->iv))) ==
240  NULL)
241  goto out;
242  if (!winpr_Cipher_Update(dec, pMemBlock->pData, pMemBlock->cbData, pPlainText, &cbOut))
243  goto out;
244  if (!winpr_Cipher_Final(dec, pPlainText + cbOut, &cbFinal))
245  goto out;
246  winpr_Cipher_Free(dec);
247 
248  CopyMemory(pMemBlock->pData, pPlainText, pMemBlock->cbData);
249  SecureZeroMemory(pPlainText, pMemBlock->cbData);
250  free(pPlainText);
251 
252  ListDictionary_Remove(g_ProtectedMemoryBlocks, pData);
253 
254  free(pMemBlock);
255 
256  return TRUE;
257 
258 out:
259  free(pPlainText);
260  free(pMemBlock);
261  winpr_Cipher_Free(dec);
262  return FALSE;
263 }
264 
265 BOOL CryptProtectData(DATA_BLOB* pDataIn, LPCWSTR szDataDescr, DATA_BLOB* pOptionalEntropy,
266  PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags,
267  DATA_BLOB* pDataOut)
268 {
269  return TRUE;
270 }
271 
272 BOOL CryptUnprotectData(DATA_BLOB* pDataIn, LPWSTR* ppszDataDescr, DATA_BLOB* pOptionalEntropy,
273  PVOID pvReserved, CRYPTPROTECT_PROMPTSTRUCT* pPromptStruct, DWORD dwFlags,
274  DATA_BLOB* pDataOut)
275 {
276  return TRUE;
277 }
278 
279 BOOL CryptStringToBinaryW(LPCWSTR pszString, DWORD cchString, DWORD dwFlags, BYTE* pbBinary,
280  DWORD* pcbBinary, DWORD* pdwSkip, DWORD* pdwFlags)
281 {
282  return TRUE;
283 }
284 
285 BOOL CryptStringToBinaryA(LPCSTR pszString, DWORD cchString, DWORD dwFlags, BYTE* pbBinary,
286  DWORD* pcbBinary, DWORD* pdwSkip, DWORD* pdwFlags)
287 {
288  return TRUE;
289 }
290 
291 BOOL CryptBinaryToStringW(CONST BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, LPWSTR pszString,
292  DWORD* pcchString)
293 {
294  return TRUE;
295 }
296 
297 BOOL CryptBinaryToStringA(CONST BYTE* pbBinary, DWORD cbBinary, DWORD dwFlags, LPSTR pszString,
298  DWORD* pcchString)
299 {
300  return TRUE;
301 }
302 
303 #endif