"Fossies" - the Fresh Open Source Software Archive

Member "src/ExpandVolume/InitDataArea.c" (10 Oct 2018, 8615 Bytes) of package /windows/misc/VeraCrypt_1.23-Hotfix-2_Source.zip:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "InitDataArea.c" see the Fossies "Dox" file reference documentation.

    1 /*
    2  Legal Notice: Some portions of the source code contained in this file were
    3  derived from the source code of TrueCrypt 7.1a, which is
    4  Copyright (c) 2003-2012 TrueCrypt Developers Association and which is
    5  governed by the TrueCrypt License 3.0, also from the source code of
    6  Encryption for the Masses 2.02a, which is Copyright (c) 1998-2000 Paul Le Roux
    7  and which is governed by the 'License Agreement for Encryption for the Masses'
    8  and also from the source code of extcv, which is Copyright (c) 2009-2010 Kih-Oskh
    9  or Copyright (c) 2012-2013 Josef Schneider <josef@netpage.dk>
   10 
   11  Modifications and additions to the original source code (contained in this file)
   12  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
   13  and are governed by the Apache License 2.0 the full text of which is
   14  contained in the file License.txt included in VeraCrypt binary and source
   15  code distribution packages. */
   16 
   17 #include <stdlib.h>
   18 #include <string.h>
   19 
   20 #include "Tcdefs.h"
   21 
   22 #include "Common.h"
   23 #include "Crypto.h"
   24 #include "Random.h"
   25 #include "Volumes.h"
   26 
   27 #include "Apidrvr.h"
   28 #include "Dlgcode.h"
   29 #include "Language.h"
   30 #include "Progress.h"
   31 #include "Resource.h"
   32 
   33 #include "InitDataArea.h"
   34 
   35 #ifndef SRC_POS
   36 #define SRC_POS (__FUNCTION__ ":" TC_TO_STRING(__LINE__))
   37 #endif
   38 
   39 int FormatWriteBufferSize = 1024 * 1024;
   40 static uint32 FormatSectorSize = 0;
   41 
   42 void SetFormatSectorSize(uint32 sector_size)
   43 {
   44     FormatSectorSize = sector_size;
   45 }
   46 
   47 int FormatNoFs (HWND hwndDlg, unsigned __int64 startSector, __int64 num_sectors, void * dev, PCRYPTO_INFO cryptoInfo, BOOL quickFormat)
   48 {
   49     int write_buf_cnt = 0;
   50     char sector[TC_MAX_VOLUME_SECTOR_SIZE], *write_buf;
   51     unsigned __int64 nSecNo = startSector;
   52     int retVal = 0;
   53     DWORD err;
   54     CRYPTOPP_ALIGN_DATA(16) char temporaryKey[MASTER_KEYDATA_SIZE];
   55     CRYPTOPP_ALIGN_DATA(16) char originalK2[MASTER_KEYDATA_SIZE];
   56 
   57     LARGE_INTEGER startOffset;
   58     LARGE_INTEGER newOffset;
   59 
   60     // Seek to start sector
   61     startOffset.QuadPart = startSector * FormatSectorSize;
   62     if (!SetFilePointerEx ((HANDLE) dev, startOffset, &newOffset, FILE_BEGIN)
   63         || newOffset.QuadPart != startOffset.QuadPart)
   64     {
   65         return ERR_OS_ERROR;
   66     }
   67 
   68     write_buf = (char *)TCalloc (FormatWriteBufferSize);
   69     if (!write_buf)
   70         return ERR_OUTOFMEMORY;
   71 
   72     VirtualLock (temporaryKey, sizeof (temporaryKey));
   73     VirtualLock (originalK2, sizeof (originalK2));
   74 
   75     memset (sector, 0, sizeof (sector));
   76 
   77     // Remember the original secondary key (XTS mode) before generating a temporary one
   78     memcpy (originalK2, cryptoInfo->k2, sizeof (cryptoInfo->k2));
   79 
   80     /* Fill the rest of the data area with random data */
   81 
   82     if(!quickFormat)
   83     {
   84         /* Generate a random temporary key set to be used for "dummy" encryption that will fill
   85         the free disk space (data area) with random data.  This is necessary for plausible
   86         deniability of hidden volumes. */
   87 
   88         // Temporary master key
   89         if (!RandgetBytes (hwndDlg, temporaryKey, EAGetKeySize (cryptoInfo->ea), FALSE))
   90             goto fail;
   91 
   92         // Temporary secondary key (XTS mode)
   93         if (!RandgetBytes (hwndDlg, cryptoInfo->k2, sizeof cryptoInfo->k2, FALSE))
   94             goto fail;
   95 
   96         retVal = EAInit (cryptoInfo->ea, temporaryKey, cryptoInfo->ks);
   97         if (retVal != ERR_SUCCESS)
   98             goto fail;
   99 
  100         if (!EAInitMode (cryptoInfo))
  101         {
  102             retVal = ERR_MODE_INIT_FAILED;
  103             goto fail;
  104         }
  105 
  106         while (num_sectors--)
  107         {
  108             if (WriteSector (dev, sector, write_buf, &write_buf_cnt, &nSecNo,
  109                 cryptoInfo) == FALSE)
  110                 goto fail;
  111         }
  112 
  113         if (!FlushFormatWriteBuffer (dev, write_buf, &write_buf_cnt, &nSecNo, cryptoInfo))
  114             goto fail;
  115     }
  116     else
  117         nSecNo = num_sectors;
  118 
  119     UpdateProgressBar (nSecNo * FormatSectorSize);
  120 
  121     // Restore the original secondary key (XTS mode) in case NTFS format fails and the user wants to try FAT immediately
  122     memcpy (cryptoInfo->k2, originalK2, sizeof (cryptoInfo->k2));
  123 
  124     // Reinitialize the encryption algorithm and mode in case NTFS format fails and the user wants to try FAT immediately
  125     retVal = EAInit (cryptoInfo->ea, cryptoInfo->master_keydata, cryptoInfo->ks);
  126     if (retVal != ERR_SUCCESS)
  127         goto fail;
  128     if (!EAInitMode (cryptoInfo))
  129     {
  130         retVal = ERR_MODE_INIT_FAILED;
  131         goto fail;
  132     }
  133 
  134     burn (temporaryKey, sizeof(temporaryKey));
  135     burn (originalK2, sizeof(originalK2));
  136     VirtualUnlock (temporaryKey, sizeof (temporaryKey));
  137     VirtualUnlock (originalK2, sizeof (originalK2));
  138     TCfree (write_buf);
  139 
  140     return 0;
  141 
  142 fail:
  143     err = GetLastError();
  144 
  145     burn (temporaryKey, sizeof(temporaryKey));
  146     burn (originalK2, sizeof(originalK2));
  147     VirtualUnlock (temporaryKey, sizeof (temporaryKey));
  148     VirtualUnlock (originalK2, sizeof (originalK2));
  149     TCfree (write_buf);
  150 
  151     SetLastError (err);
  152     return (retVal ? retVal : ERR_OS_ERROR);
  153 }
  154 
  155 
  156 BOOL WriteSector (void *dev, char *sector,
  157          char *write_buf, int *write_buf_cnt,
  158          __int64 *nSecNo, PCRYPTO_INFO cryptoInfo)
  159 {
  160     static __int32 updateTime = 0;
  161 
  162     (*nSecNo)++;
  163 
  164     memcpy (write_buf + *write_buf_cnt, sector, FormatSectorSize);
  165     (*write_buf_cnt) += FormatSectorSize;
  166 
  167     if (*write_buf_cnt == FormatWriteBufferSize && !FlushFormatWriteBuffer (dev, write_buf, write_buf_cnt, nSecNo, cryptoInfo))
  168         return FALSE;
  169 
  170     if (GetTickCount () - updateTime > 25)
  171     {
  172         if (UpdateProgressBar (*nSecNo * FormatSectorSize))
  173             return FALSE;
  174 
  175         updateTime = GetTickCount ();
  176     }
  177 
  178     return TRUE;
  179 
  180 }
  181 
  182 
  183 static volatile BOOL WriteThreadRunning;
  184 static volatile BOOL WriteThreadExitRequested;
  185 static HANDLE WriteThreadHandle;
  186 
  187 static byte *WriteThreadBuffer;
  188 static HANDLE WriteBufferEmptyEvent;
  189 static HANDLE WriteBufferFullEvent;
  190 
  191 static volatile HANDLE WriteRequestHandle;
  192 static volatile int WriteRequestSize;
  193 static volatile DWORD WriteRequestResult;
  194 
  195 
  196 static void __cdecl FormatWriteThreadProc (void *arg)
  197 {
  198     DWORD bytesWritten;
  199 
  200     SetThreadPriority (GetCurrentThread(), THREAD_PRIORITY_HIGHEST);
  201 
  202     while (!WriteThreadExitRequested)
  203     {
  204         if (WaitForSingleObject (WriteBufferFullEvent, INFINITE) == WAIT_FAILED)
  205         {
  206             handleWin32Error (NULL, SRC_POS);
  207             break;
  208         }
  209 
  210         if (WriteThreadExitRequested)
  211             break;
  212 
  213         if (!WriteFile (WriteRequestHandle, WriteThreadBuffer, WriteRequestSize, &bytesWritten, NULL))
  214             WriteRequestResult = GetLastError();
  215         else
  216             WriteRequestResult = ERROR_SUCCESS;
  217 
  218         if (!SetEvent (WriteBufferEmptyEvent))
  219         {
  220             handleWin32Error (NULL, SRC_POS);
  221             break;
  222         }
  223     }
  224 
  225     WriteThreadRunning = FALSE;
  226     _endthread();
  227 }
  228 
  229 
  230 BOOL StartFormatWriteThread ()
  231 {
  232     DWORD sysErr;
  233 
  234     WriteBufferEmptyEvent = NULL;
  235     WriteBufferFullEvent = NULL;
  236     WriteThreadBuffer = NULL;
  237 
  238     WriteBufferEmptyEvent = CreateEvent (NULL, FALSE, TRUE, NULL);
  239     if (!WriteBufferEmptyEvent)
  240         goto err;
  241 
  242     WriteBufferFullEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
  243     if (!WriteBufferFullEvent)
  244         goto err;
  245 
  246     WriteThreadBuffer = TCalloc (FormatWriteBufferSize);
  247     if (!WriteThreadBuffer)
  248     {
  249         SetLastError (ERROR_OUTOFMEMORY);
  250         goto err;
  251     }
  252 
  253     WriteThreadExitRequested = FALSE;
  254     WriteRequestResult = ERROR_SUCCESS;
  255 
  256     WriteThreadHandle = (HANDLE) _beginthread (FormatWriteThreadProc, 0, NULL);
  257     if ((uintptr_t) WriteThreadHandle == -1L)
  258         goto err;
  259 
  260     WriteThreadRunning = TRUE;
  261     return TRUE;
  262 
  263 err:
  264     sysErr = GetLastError();
  265 
  266     if (WriteBufferEmptyEvent)
  267         CloseHandle (WriteBufferEmptyEvent);
  268     if (WriteBufferFullEvent)
  269         CloseHandle (WriteBufferFullEvent);
  270     if (WriteThreadBuffer)
  271         TCfree (WriteThreadBuffer);
  272 
  273     SetLastError (sysErr);
  274     return FALSE;
  275 }
  276 
  277 
  278 void StopFormatWriteThread ()
  279 {
  280     if (WriteThreadRunning)
  281     {
  282         WaitForSingleObject (WriteBufferEmptyEvent, INFINITE);
  283 
  284         WriteThreadExitRequested = TRUE;
  285         SetEvent (WriteBufferFullEvent);
  286 
  287         WaitForSingleObject (WriteThreadHandle, INFINITE);
  288     }
  289 
  290     CloseHandle (WriteBufferEmptyEvent);
  291     CloseHandle (WriteBufferFullEvent);
  292     TCfree (WriteThreadBuffer);
  293 }
  294 
  295 
  296 BOOL FlushFormatWriteBuffer (void *dev, char *write_buf, int *write_buf_cnt, __int64 *nSecNo, PCRYPTO_INFO cryptoInfo)
  297 {
  298     UINT64_STRUCT unitNo;
  299     DWORD bytesWritten;
  300 
  301     if (*write_buf_cnt == 0)
  302         return TRUE;
  303 
  304     unitNo.Value = (*nSecNo * FormatSectorSize - *write_buf_cnt) / ENCRYPTION_DATA_UNIT_SIZE;
  305 
  306     EncryptDataUnits (write_buf, &unitNo, *write_buf_cnt / ENCRYPTION_DATA_UNIT_SIZE, cryptoInfo);
  307 
  308     if (WriteThreadRunning)
  309     {
  310         if (WaitForSingleObject (WriteBufferEmptyEvent, INFINITE) == WAIT_FAILED)
  311             return FALSE;
  312 
  313         if (WriteRequestResult != ERROR_SUCCESS)
  314         {
  315             SetEvent (WriteBufferEmptyEvent);
  316             SetLastError (WriteRequestResult);
  317             return FALSE;
  318         }
  319 
  320         memcpy (WriteThreadBuffer, write_buf, *write_buf_cnt);
  321         WriteRequestHandle = dev;
  322         WriteRequestSize = *write_buf_cnt;
  323 
  324         if (!SetEvent (WriteBufferFullEvent))
  325             return FALSE;
  326     }
  327     else
  328     {
  329         if (!WriteFile ((HANDLE) dev, write_buf, *write_buf_cnt, &bytesWritten, NULL))
  330             return FALSE;
  331     }
  332 
  333     *write_buf_cnt = 0;
  334     return TRUE;
  335 }