"Fossies" - the Fresh Open Source Software Archive

Member "src/Common/Crypto.c" (10 Oct 2018, 29156 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 "Crypto.c" see the Fossies "Dox" file reference documentation and the last Fossies "Diffs" side-by-side code changes report: 1.21_Source_vs_1.22_Source.

    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  Modifications and additions to the original source code (contained in this file) 
    9  and all other portions of this file are Copyright (c) 2013-2017 IDRIX
   10  and are governed by the Apache License 2.0 the full text of which is
   11  contained in the file License.txt included in VeraCrypt binary and source
   12  code distribution packages. */
   13 
   14 #include "Tcdefs.h"
   15 #include "Crypto.h"
   16 #include "Xts.h"
   17 #include "Crc.h"
   18 #include "Common/Endian.h"
   19 #if !defined(_UEFI)
   20 #include <string.h>
   21 #ifndef TC_WINDOWS_BOOT
   22 #include "EncryptionThreadPool.h"
   23 #endif
   24 #endif
   25 #include "Volumes.h"
   26 #include "cpu.h"
   27 
   28 #pragma warning (disable:4706) // assignment within conditional expression
   29 /* Update the following when adding a new cipher or EA:
   30 
   31    Crypto.h:
   32      ID #define
   33      MAX_EXPANDED_KEY #define
   34 
   35    Crypto.c:
   36      Ciphers[]
   37      EncryptionAlgorithms[]
   38      CipherInit()
   39      EncipherBlock()
   40      DecipherBlock()
   41 
   42 */
   43 
   44 #ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
   45 
   46 // Cipher configuration
   47 static Cipher Ciphers[] =
   48 {
   49 //                              Block Size  Key Size    Key Schedule Size
   50 //    ID        Name            (Bytes)     (Bytes)     (Bytes)
   51 #ifdef TC_WINDOWS_BOOT
   52     { AES,      "AES",          16,         32,         AES_KS              },
   53     { SERPENT,  "Serpent",      16,         32,         140*4               },
   54     { TWOFISH,  "Twofish",      16,         32,         TWOFISH_KS          },
   55 #else
   56     { AES,      L"AES",         16,         32,         AES_KS              },
   57     { SERPENT,  L"Serpent",     16,         32,         140*4               },
   58     { TWOFISH,  L"Twofish",     16,         32,         TWOFISH_KS          },
   59     { CAMELLIA, L"Camellia",    16,         32,         CAMELLIA_KS         },
   60 #if defined(CIPHER_GOST89)
   61     { GOST89,   L"GOST89",      16,         32,         GOST_KS },
   62 #endif  // defined(CIPHER_GOST89)
   63     { KUZNYECHIK,   L"Kuznyechik",16,       32,         KUZNYECHIK_KS },
   64 #endif
   65     { 0,        0,              0,          0,          0                   }
   66 };
   67 
   68 
   69 // Encryption algorithm configuration
   70 static EncryptionAlgorithm EncryptionAlgorithms[] =
   71 {
   72     //  Cipher(s)                     Modes                     FormatEnabled
   73 
   74 #ifndef TC_WINDOWS_BOOT
   75 
   76     { { 0,                          0 }, { 0, 0},       0, 0 }, // Must be all-zero
   77     { { AES,                            0 }, { XTS, 0 },    1, 1 },
   78     { { SERPENT,                    0 }, { XTS, 0 },    1, 1 },
   79     { { TWOFISH,                    0 }, { XTS, 0 },    1, 1 },
   80     { { CAMELLIA,                   0 }, { XTS, 0 },    1, 1 },
   81 #if defined(CIPHER_GOST89)
   82     { { GOST89,                     0 }, { XTS, 0 },    0, 0 },
   83 #endif  // defined(CIPHER_GOST89)
   84     { { KUZNYECHIK,             0 }, { XTS, 0 },    0, 1 },
   85     { { TWOFISH, AES,               0 }, { XTS, 0 },    1, 1 },
   86     { { SERPENT, TWOFISH, AES,  0 }, { XTS, 0 },    1, 1 },
   87     { { AES, SERPENT,               0 }, { XTS, 0 },    1, 1 },
   88     { { AES, TWOFISH, SERPENT,  0 }, { XTS, 0 },    1, 1 },
   89     { { SERPENT, TWOFISH,       0 }, { XTS, 0 },    1, 1 },
   90     { { KUZNYECHIK, CAMELLIA,       0 }, { XTS, 0 },    0, 1 },
   91     { { TWOFISH, KUZNYECHIK,        0 }, { XTS, 0 },    0, 1 },
   92     { { SERPENT, CAMELLIA,      0 }, { XTS, 0 },    0, 1 },
   93     { { AES, KUZNYECHIK,        0 }, { XTS, 0 },    0, 1 },
   94     { { CAMELLIA, SERPENT, KUZNYECHIK,  0 }, { XTS, 0 },    0, 1 },
   95     { { 0,                          0 }, { 0,    0},    0, 0 }      // Must be all-zero
   96 
   97 #else // TC_WINDOWS_BOOT
   98 
   99     // Encryption algorithms available for boot drive encryption
  100     { { 0,                      0 }, { 0, 0 },      0 },    // Must be all-zero
  101     { { AES,                    0 }, { XTS, 0 },    1 },
  102     { { SERPENT,                0 }, { XTS, 0 },    1 },
  103     { { TWOFISH,                0 }, { XTS, 0 },    1 },
  104     { { TWOFISH, AES,           0 }, { XTS, 0 },    1 },
  105     { { SERPENT, TWOFISH, AES,  0 }, { XTS, 0 },    1 },
  106     { { AES, SERPENT,           0 }, { XTS, 0 },    1 },
  107     { { AES, TWOFISH, SERPENT,  0 }, { XTS, 0 },    1 },
  108     { { SERPENT, TWOFISH,       0 }, { XTS, 0 },    1 },
  109     { { 0,                      0 }, { 0, 0 },      0 },    // Must be all-zero
  110 
  111 #endif
  112 
  113 };
  114 
  115 
  116 #ifndef TC_WINDOWS_BOOT
  117 // Hash algorithms
  118 static Hash Hashes[] =
  119 {   // ID               Name                    Deprecated  System Encryption
  120     { SHA512,       L"SHA-512",             FALSE,  FALSE },
  121     { WHIRLPOOL,    L"Whirlpool",           FALSE,  FALSE },
  122     { SHA256,       L"SHA-256",             FALSE,  TRUE },
  123     { RIPEMD160,    L"RIPEMD-160",          TRUE,       TRUE },
  124     { STREEBOG,     L"Streebog",    FALSE,  FALSE },
  125     { 0, 0, 0 }
  126 };
  127 #endif
  128 
  129 /* Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal) */
  130 int CipherInit (int cipher, unsigned char *key, unsigned __int8 *ks)
  131 {
  132     int retVal = ERR_SUCCESS;
  133 
  134     switch (cipher)
  135     {
  136     case AES:
  137 #ifndef TC_WINDOWS_BOOT
  138         if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
  139             return ERR_CIPHER_INIT_FAILURE;
  140 
  141         if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof(aes_encrypt_ctx))) != EXIT_SUCCESS)
  142             return ERR_CIPHER_INIT_FAILURE;
  143 #else
  144         if (aes_set_key (key, (length_type) CipherGetKeySize(AES), (aes_context *) ks) != 0)
  145             return ERR_CIPHER_INIT_FAILURE;
  146 #endif
  147         break;
  148 
  149     case SERPENT:
  150         serpent_set_key (key, ks);
  151         break;
  152         
  153     case TWOFISH:
  154         twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key);
  155         break;
  156 
  157 #if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
  158     case CAMELLIA:
  159         camellia_set_key (key, ks);
  160         break;
  161 #endif
  162 
  163 #if !defined(TC_WINDOWS_BOOT) 
  164 #if defined(CIPHER_GOST89)
  165     case GOST89:
  166         gost_set_key(key, (gost_kds*)ks, 1);
  167         break;
  168 #endif // && defined(CIPHER_GOST89)
  169     case KUZNYECHIK:
  170         kuznyechik_set_key(key, (kuznyechik_kds*)ks);
  171         break;
  172 #endif // !defined(TC_WINDOWS_BOOT)
  173 
  174     default:
  175         // Unknown/wrong cipher ID
  176         return ERR_CIPHER_INIT_FAILURE;
  177     }
  178 
  179     return retVal;
  180 }
  181 
  182 void EncipherBlock(int cipher, void *data, void *ks)
  183 {
  184     switch (cipher)
  185     {
  186     case AES:   
  187         // In 32-bit kernel mode, due to KeSaveFloatingPointState() overhead, AES instructions can be used only when processing the whole data unit.
  188 #if (defined (_WIN64) || !defined (TC_WINDOWS_DRIVER)) && !defined (TC_WINDOWS_BOOT)
  189         if (IsAesHwCpuSupported())
  190             aes_hw_cpu_encrypt (ks, data);
  191         else
  192 #endif
  193             aes_encrypt (data, data, ks);
  194         break;
  195 
  196     case TWOFISH:       twofish_encrypt (ks, data, data); break;
  197     case SERPENT:       serpent_encrypt (data, data, ks); break;
  198 #if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
  199     case CAMELLIA:      camellia_encrypt (data, data, ks); break;
  200 #endif
  201 #if !defined(TC_WINDOWS_BOOT)
  202 #if defined(CIPHER_GOST89)
  203     case GOST89:        gost_encrypt(data, data, ks, 1); break;
  204 #endif // defined(CIPHER_GOST89)
  205     case KUZNYECHIK:        kuznyechik_encrypt_block(data, data, ks); break;
  206 #endif // !defined(TC_WINDOWS_BOOT) 
  207     default:            TC_THROW_FATAL_EXCEPTION;   // Unknown/wrong ID
  208     }
  209 }
  210 
  211 #ifndef TC_WINDOWS_BOOT
  212 
  213 void EncipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
  214 {
  215     byte *data = dataPtr;
  216 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  217     KFLOATING_SAVE floatingPointState;
  218 #endif
  219 
  220     if (cipher == AES
  221         && (blockCount & (32 - 1)) == 0
  222         && IsAesHwCpuSupported()
  223 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  224         && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))
  225 #endif
  226         )
  227     {
  228         while (blockCount > 0)
  229         {
  230             aes_hw_cpu_encrypt_32_blocks (ks, data);
  231 
  232             data += 32 * 16;
  233             blockCount -= 32;
  234         }
  235 
  236 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  237         KeRestoreFloatingPointState (&floatingPointState);
  238 #endif
  239     }
  240 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
  241     else if (cipher == SERPENT
  242             && (blockCount >= 4)
  243             && HasSSE2()
  244 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  245             && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))
  246 #endif
  247         )
  248     {
  249         serpent_encrypt_blocks (data, data, blockCount, ks);
  250 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  251         KeRestoreFloatingPointState (&floatingPointState);
  252 #endif
  253     }
  254 #endif
  255 #if CRYPTOPP_BOOL_X64
  256    else if (cipher == TWOFISH)  {
  257             twofish_encrypt_blocks(ks, data, data, (uint32) blockCount);
  258     }
  259     else if (cipher == CAMELLIA)    {
  260             camellia_encrypt_blocks(ks, data, data, (uint32) blockCount);
  261     }
  262 #endif
  263 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
  264     else if (cipher == KUZNYECHIK
  265             && HasSSE2()
  266 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  267             && (blockCount >= 4) && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))
  268 #endif
  269         )
  270     {
  271         kuznyechik_encrypt_blocks (data, data, blockCount, ks);
  272 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  273         KeRestoreFloatingPointState (&floatingPointState);
  274 #endif
  275     }
  276 #endif
  277     else if (cipher == GOST89)  {
  278             gost_encrypt(data, data, ks, (int)blockCount);
  279     }
  280     else
  281     {
  282         size_t blockSize = CipherGetBlockSize (cipher);
  283         while (blockCount-- > 0)
  284         {
  285             EncipherBlock (cipher, data, ks);
  286             data += blockSize;
  287         }
  288     }
  289 }
  290 
  291 #endif // !TC_WINDOWS_BOOT
  292 
  293 void DecipherBlock(int cipher, void *data, void *ks)
  294 {
  295     switch (cipher)
  296     {
  297     case SERPENT:   serpent_decrypt (data, data, ks); break;
  298     case TWOFISH:   twofish_decrypt (ks, data, data); break;
  299 #if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_CAMELLIA)
  300     case CAMELLIA:  camellia_decrypt (data, data, ks); break;
  301 #endif
  302 #if !defined(TC_WINDOWS_BOOT)
  303 #if defined(CIPHER_GOST89)
  304     case GOST89:    gost_decrypt(data, data, ks, 1); break;
  305 #endif // defined(CIPHER_GOST89)
  306     case KUZNYECHIK:    kuznyechik_decrypt_block(data, data, ks); break;
  307 #endif // !defined(TC_WINDOWS_BOOT)
  308 
  309 
  310 #ifndef TC_WINDOWS_BOOT
  311 
  312     case AES:
  313 #if defined (_WIN64) || !defined (TC_WINDOWS_DRIVER)
  314         if (IsAesHwCpuSupported())
  315             aes_hw_cpu_decrypt ((byte *) ks + sizeof (aes_encrypt_ctx), data);
  316         else
  317 #endif
  318             aes_decrypt (data, data, (void *) ((char *) ks + sizeof(aes_encrypt_ctx)));
  319         break;
  320 
  321 #else
  322     case AES:       aes_decrypt (data, data, ks); break;
  323 #endif
  324     default:        TC_THROW_FATAL_EXCEPTION;   // Unknown/wrong ID
  325     }
  326 }
  327 
  328 #ifndef TC_WINDOWS_BOOT
  329 
  330 void DecipherBlocks (int cipher, void *dataPtr, void *ks, size_t blockCount)
  331 {
  332     byte *data = dataPtr;
  333 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  334     KFLOATING_SAVE floatingPointState;
  335 #endif
  336 
  337     if (cipher == AES
  338         && (blockCount & (32 - 1)) == 0
  339         && IsAesHwCpuSupported()
  340 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  341         && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))
  342 #endif
  343         )
  344     {
  345         while (blockCount > 0)
  346         {
  347             aes_hw_cpu_decrypt_32_blocks ((byte *) ks + sizeof (aes_encrypt_ctx), data);
  348 
  349             data += 32 * 16;
  350             blockCount -= 32;
  351         }
  352 
  353 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  354         KeRestoreFloatingPointState (&floatingPointState);
  355 #endif
  356     }
  357 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
  358     else if (cipher == SERPENT
  359             && (blockCount >= 4)
  360             && HasSSE2()
  361 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  362             && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))
  363 #endif
  364         )
  365     {
  366         serpent_decrypt_blocks (data, data, blockCount, ks);
  367 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  368         KeRestoreFloatingPointState (&floatingPointState);
  369 #endif
  370     }
  371 #endif
  372 #if CRYPTOPP_BOOL_X64
  373    else if (cipher == TWOFISH)  {
  374             twofish_decrypt_blocks(ks, data, data, (uint32) blockCount);
  375     }
  376     else if (cipher == CAMELLIA)    {
  377             camellia_decrypt_blocks(ks, data, data, (uint32) blockCount);
  378     }
  379 #endif
  380 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
  381     else if (cipher == KUZNYECHIK           
  382             && HasSSE2()
  383 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  384             && (blockCount >= 4) && NT_SUCCESS (KeSaveFloatingPointState (&floatingPointState))
  385 #endif
  386         )
  387     {
  388         kuznyechik_decrypt_blocks (data, data, blockCount, ks);
  389 #if defined (TC_WINDOWS_DRIVER) && !defined (_WIN64)
  390         KeRestoreFloatingPointState (&floatingPointState);
  391 #endif
  392     }
  393 #endif
  394     else if (cipher == GOST89)  {
  395             gost_decrypt(data, data, ks, (int)blockCount);
  396     }
  397     else
  398     {
  399         size_t blockSize = CipherGetBlockSize (cipher);
  400         while (blockCount-- > 0)
  401         {
  402             DecipherBlock (cipher, data, ks);
  403             data += blockSize;
  404         }
  405     }
  406 }
  407 
  408 #endif // !TC_WINDOWS_BOOT
  409 
  410 
  411 // Ciphers support
  412 
  413 Cipher *CipherGet (int id)
  414 {
  415     int i;
  416     for (i = 0; Ciphers[i].Id != 0; i++)
  417         if (Ciphers[i].Id == id)
  418             return &Ciphers[i];
  419 
  420     return NULL;
  421 }
  422 
  423 #ifndef TC_WINDOWS_BOOT
  424 const wchar_t *CipherGetName (int cipherId)
  425 {
  426    Cipher* pCipher = CipherGet (cipherId);
  427    return  pCipher? pCipher -> Name : L"";
  428 }
  429 
  430 int CipherGetBlockSize (int cipherId)
  431 {
  432    Cipher* pCipher = CipherGet (cipherId);
  433    return pCipher? pCipher -> BlockSize : 0;
  434 }
  435 #endif
  436 
  437 int CipherGetKeySize (int cipherId)
  438 {
  439 #ifdef TC_WINDOWS_BOOT
  440     return CipherGet (cipherId) -> KeySize;
  441 #else
  442    Cipher* pCipher = CipherGet (cipherId);
  443    return pCipher? pCipher -> KeySize : 0;
  444 #endif
  445 }
  446 
  447 int CipherGetKeyScheduleSize (int cipherId)
  448 {
  449 #ifdef TC_WINDOWS_BOOT
  450     return CipherGet (cipherId) -> KeyScheduleSize;
  451 #else
  452    Cipher* pCipher = CipherGet (cipherId);
  453    return pCipher? pCipher -> KeyScheduleSize : 0;
  454 #endif
  455 }
  456 
  457 #ifndef TC_WINDOWS_BOOT
  458 
  459 BOOL CipherSupportsIntraDataUnitParallelization (int cipher)
  460 {
  461     return (cipher == AES && IsAesHwCpuSupported()) 
  462         || (cipher == GOST89)
  463 #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined (_UEFI)
  464         || (cipher == SERPENT && HasSSE2())
  465         || (cipher == KUZNYECHIK && HasSSE2())
  466 #endif
  467 #if CRYPTOPP_BOOL_X64
  468         || (cipher == TWOFISH)
  469         || (cipher == CAMELLIA)
  470 #endif
  471         ;
  472 }
  473 
  474 #endif
  475 
  476 
  477 // Encryption algorithms support
  478 
  479 int EAGetFirst ()
  480 {
  481     return 1;
  482 }
  483 
  484 #ifndef TC_WINDOWS_BOOT
  485 // Returns number of EAs
  486 int EAGetCount (void)
  487 {
  488     int ea, count = 0;
  489 
  490     for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
  491     {
  492         count++;
  493     }
  494     return count;
  495 }
  496 #endif
  497 
  498 int EAGetNext (int previousEA)
  499 {
  500     int id = previousEA + 1;
  501     if (EncryptionAlgorithms[id].Ciphers[0] != 0) return id;
  502     return 0;
  503 }
  504 
  505 
  506 // Return values: 0 = success, ERR_CIPHER_INIT_FAILURE (fatal), ERR_CIPHER_INIT_WEAK_KEY (non-fatal)
  507 int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
  508 {
  509     int c, retVal = ERR_SUCCESS;
  510 
  511     if (ea == 0)
  512         return ERR_CIPHER_INIT_FAILURE;
  513 
  514     for (c = EAGetFirstCipher (ea); c != 0; c = EAGetNextCipher (ea, c))
  515     {
  516         switch (CipherInit (c, key, ks))
  517         {
  518         case ERR_CIPHER_INIT_FAILURE:
  519             return ERR_CIPHER_INIT_FAILURE;
  520 
  521         case ERR_CIPHER_INIT_WEAK_KEY:
  522             retVal = ERR_CIPHER_INIT_WEAK_KEY;      // Non-fatal error
  523             break;
  524         }
  525 
  526         key += CipherGetKeySize (c);
  527         ks += CipherGetKeyScheduleSize (c);
  528     }
  529     return retVal;
  530 }
  531 
  532 
  533 #ifndef TC_WINDOWS_BOOT
  534 
  535 BOOL EAInitMode (PCRYPTO_INFO ci)
  536 {
  537     switch (ci->mode)
  538     {
  539     case XTS:
  540         // Secondary key schedule
  541         if (EAInit (ci->ea, ci->k2, ci->ks2) != ERR_SUCCESS)
  542             return FALSE;
  543 
  544         /* Note: XTS mode could potentially be initialized with a weak key causing all blocks in one data unit
  545         on the volume to be tweaked with zero tweaks (i.e. 512 bytes of the volume would be encrypted in ECB
  546         mode). However, to create a TrueCrypt volume with such a weak key, each human being on Earth would have
  547         to create approximately 11,378,125,361,078,862 (about eleven quadrillion) TrueCrypt volumes (provided 
  548         that the size of each of the volumes is 1024 terabytes). */
  549         break;
  550 
  551     default:        
  552         // Unknown/wrong ID
  553         TC_THROW_FATAL_EXCEPTION;
  554     }
  555     return TRUE;
  556 }
  557 
  558 static void EAGetDisplayName(wchar_t *buf, int ea, int i)
  559 {
  560     wcscpy (buf, CipherGetName (i));
  561     if (i = EAGetPreviousCipher(ea, i))
  562     {
  563         wcscat (buf, L"(");
  564         EAGetDisplayName (&buf[wcslen(buf)], ea, i);
  565         wcscat (buf, L")");
  566     }
  567 }
  568 
  569 // Returns name of EA, cascaded cipher names are separated by hyphens
  570 wchar_t *EAGetName (wchar_t *buf, int ea, int guiDisplay)
  571 {
  572     if (guiDisplay)
  573     {
  574         EAGetDisplayName (buf, ea, EAGetLastCipher(ea));
  575     }
  576     else
  577     {
  578         int i = EAGetLastCipher(ea);
  579         wcscpy (buf, (i != 0) ? CipherGetName (i) : L"?");
  580 
  581         while (i = EAGetPreviousCipher(ea, i))
  582         {
  583             wcscat (buf, L"-");
  584             wcscat (buf, CipherGetName (i));
  585         }
  586     }
  587     return buf;
  588 }
  589 
  590 
  591 int EAGetByName (wchar_t *name)
  592 {
  593     int ea = EAGetFirst ();
  594     wchar_t n[128];
  595 
  596     do
  597     {
  598         EAGetName(n, ea, 1);
  599 #if defined(_UEFI)
  600         if (wcscmp(n, name) == 0)
  601 #else
  602         if (_wcsicmp(n, name) == 0)
  603 #endif
  604             return ea;
  605     }
  606     while (ea = EAGetNext (ea));
  607 
  608     return 0;
  609 }
  610 
  611 #endif // TC_WINDOWS_BOOT
  612 
  613 // Returns sum of key sizes of all ciphers of the EA (in bytes)
  614 int EAGetKeySize (int ea)
  615 {
  616     int i = EAGetFirstCipher (ea);
  617     int size = CipherGetKeySize (i);
  618 
  619     while (i = EAGetNextCipher (ea, i))
  620     {
  621         size += CipherGetKeySize (i);
  622     }
  623 
  624     return size;
  625 }
  626 
  627 
  628 #ifndef TC_WINDOWS_BOOT
  629 
  630 // Returns the first mode of operation of EA
  631 int EAGetFirstMode (int ea)
  632 {
  633     return (EncryptionAlgorithms[ea].Modes[0]);
  634 }
  635 
  636 
  637 int EAGetNextMode (int ea, int previousModeId)
  638 {
  639     int c, i = 0;
  640     while (c = EncryptionAlgorithms[ea].Modes[i++])
  641     {
  642         if (c == previousModeId) 
  643             return EncryptionAlgorithms[ea].Modes[i];
  644     }
  645 
  646     return 0;
  647 }
  648 
  649 // Returns the name of the mode of operation of the whole EA
  650 wchar_t *EAGetModeName (int ea, int mode, BOOL capitalLetters)
  651 {
  652     switch (mode)
  653     {
  654     case XTS:
  655 
  656         return L"XTS";
  657 
  658     }
  659     return L"[unknown]";
  660 }
  661 
  662 #endif // TC_WINDOWS_BOOT
  663 
  664 
  665 // Returns sum of key schedule sizes of all ciphers of the EA
  666 int EAGetKeyScheduleSize (int ea)
  667 {
  668     int i = EAGetFirstCipher(ea);
  669     int size = CipherGetKeyScheduleSize (i);
  670 
  671     while (i = EAGetNextCipher(ea, i))
  672     {
  673         size += CipherGetKeyScheduleSize (i);
  674     }
  675 
  676     return size;
  677 }
  678 
  679 #ifndef TC_WINDOWS_BOOT
  680 
  681 // Returns number of ciphers in EA
  682 int EAGetCipherCount (int ea)
  683 {
  684     int i = 0;
  685     while (EncryptionAlgorithms[ea].Ciphers[i++]);
  686 
  687     return i - 1;
  688 }
  689 
  690 #endif
  691 
  692 int EAGetFirstCipher (int ea)
  693 {
  694     return EncryptionAlgorithms[ea].Ciphers[0];
  695 }
  696 
  697 
  698 int EAGetLastCipher (int ea)
  699 {
  700     int c, i = 0;
  701     while (c = EncryptionAlgorithms[ea].Ciphers[i++]);
  702 
  703     return EncryptionAlgorithms[ea].Ciphers[i - 2];
  704 }
  705 
  706 
  707 int EAGetNextCipher (int ea, int previousCipherId)
  708 {
  709     int c, i = 0;
  710     while (c = EncryptionAlgorithms[ea].Ciphers[i++])
  711     {
  712         if (c == previousCipherId) 
  713             return EncryptionAlgorithms[ea].Ciphers[i];
  714     }
  715 
  716     return 0;
  717 }
  718 
  719 
  720 int EAGetPreviousCipher (int ea, int previousCipherId)
  721 {
  722     int c, i = 0;
  723 
  724     if (EncryptionAlgorithms[ea].Ciphers[i++] == previousCipherId)
  725         return 0;
  726 
  727     while (c = EncryptionAlgorithms[ea].Ciphers[i++])
  728     {
  729         if (c == previousCipherId) 
  730             return EncryptionAlgorithms[ea].Ciphers[i - 2];
  731     }
  732 
  733     return 0;
  734 }
  735 
  736 #ifndef TC_WINDOWS_BOOT
  737 int EAIsFormatEnabled (int ea)
  738 {
  739     return EncryptionAlgorithms[ea].FormatEnabled;
  740 }
  741 
  742 int EAIsMbrSysEncEnabled (int ea)
  743 {
  744     return EncryptionAlgorithms[ea].MbrSysEncEnabled;
  745 }
  746 
  747 // Returns TRUE if the mode of operation is supported for the encryption algorithm
  748 BOOL EAIsModeSupported (int ea, int testedMode)
  749 {
  750     int mode;
  751 
  752     for (mode = EAGetFirstMode (ea); mode != 0; mode = EAGetNextMode (ea, mode))
  753     {
  754         if (mode == testedMode)
  755             return TRUE;
  756     }
  757     return FALSE;
  758 }
  759 
  760 Hash *HashGet (int id)
  761 {
  762     int i;
  763     for (i = 0; Hashes[i].Id != 0; i++)
  764         if (Hashes[i].Id == id)
  765             return &Hashes[i];
  766 
  767     return 0;
  768 }
  769 
  770 #ifdef _WIN32
  771 int HashGetIdByName (wchar_t *name)
  772 {
  773     int i;
  774     for (i = 0; Hashes[i].Id != 0; i++)
  775         if (_wcsicmp (Hashes[i].Name, name) == 0)
  776             return Hashes[i].Id;
  777 
  778     return 0;
  779 }
  780 #endif
  781 
  782 const wchar_t *HashGetName (int hashId)
  783 {
  784    Hash* pHash = HashGet(hashId);
  785    return pHash? pHash -> Name : L"";
  786 }
  787 
  788 void HashGetName2 (wchar_t *buf, int hashId)
  789 {
  790    Hash* pHash = HashGet(hashId);
  791    if (pHash)
  792         wcscpy(buf, pHash -> Name);
  793     else
  794         buf[0] = L'\0';
  795 }
  796 
  797 BOOL HashIsDeprecated (int hashId)
  798 {
  799    Hash* pHash = HashGet(hashId);
  800    return pHash? pHash -> Deprecated : FALSE;
  801 
  802 }
  803 
  804 BOOL HashForSystemEncryption (int hashId)
  805 {
  806    Hash* pHash = HashGet(hashId);
  807    return pHash? pHash -> SystemEncryption : FALSE;
  808 
  809 }
  810 
  811 // Returns the largest key size needed by an EA for the specified mode of operation
  812 int EAGetLargestKeyForMode (int mode)
  813 {
  814     int ea, key = 0;
  815 
  816     for (ea = EAGetFirst (); ea != 0; ea = EAGetNext (ea))
  817     {
  818         if (!EAIsModeSupported (ea, mode))
  819             continue;
  820 
  821         if (EAGetKeySize (ea) >= key)
  822             key = EAGetKeySize (ea);
  823     }
  824     return key;
  825 }
  826 
  827 // Returns the maximum number of bytes necessary to be generated by the PBKDF2 (PKCS #5)
  828 int GetMaxPkcs5OutSize (void)
  829 {
  830     int size = 32;
  831 
  832     size = VC_MAX (size, EAGetLargestKeyForMode (XTS) * 2); // Sizes of primary + secondary keys
  833 
  834     return size;
  835 }
  836 
  837 #endif
  838 
  839 
  840 #endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  841 
  842 
  843 #ifdef TC_WINDOWS_BOOT
  844 
  845 static byte CryptoInfoBufferInUse = 0;
  846 CRYPTO_INFO CryptoInfoBuffer;
  847 
  848 #endif
  849 
  850 PCRYPTO_INFO crypto_open ()
  851 {
  852 #ifndef TC_WINDOWS_BOOT
  853 
  854     /* Do the crt allocation */
  855     PCRYPTO_INFO cryptoInfo = (PCRYPTO_INFO) TCalloc (sizeof (CRYPTO_INFO));
  856     if (cryptoInfo == NULL)
  857         return NULL;
  858 
  859     memset (cryptoInfo, 0, sizeof (CRYPTO_INFO));
  860 
  861 #if !defined(DEVICE_DRIVER) && !defined(_UEFI)
  862     VirtualLock (cryptoInfo, sizeof (CRYPTO_INFO));
  863 #endif
  864 
  865     cryptoInfo->ea = -1;
  866     return cryptoInfo;
  867 
  868 #else // TC_WINDOWS_BOOT
  869 
  870 #if 0
  871     if (CryptoInfoBufferInUse)
  872         TC_THROW_FATAL_EXCEPTION;
  873 #endif
  874     CryptoInfoBufferInUse = 1;
  875     return &CryptoInfoBuffer;
  876 
  877 #endif // TC_WINDOWS_BOOT
  878 }
  879 
  880 #ifndef TC_WINDOWS_BOOT
  881 void crypto_loadkey (PKEY_INFO keyInfo, char *lpszUserKey, int nUserKeyLen)
  882 {
  883     keyInfo->keyLength = nUserKeyLen;
  884     burn (keyInfo->userKey, sizeof (keyInfo->userKey));
  885     memcpy (keyInfo->userKey, lpszUserKey, nUserKeyLen);
  886 }
  887 #endif
  888 
  889 void crypto_close (PCRYPTO_INFO cryptoInfo)
  890 {
  891 #ifndef TC_WINDOWS_BOOT
  892 
  893     if (cryptoInfo != NULL)
  894     {
  895         burn (cryptoInfo, sizeof (CRYPTO_INFO));
  896 #if !defined(DEVICE_DRIVER) && !defined(_UEFI)
  897         VirtualUnlock (cryptoInfo, sizeof (CRYPTO_INFO));
  898 #endif
  899         TCfree (cryptoInfo);
  900     }
  901 
  902 #else // TC_WINDOWS_BOOT
  903 
  904     burn (&CryptoInfoBuffer, sizeof (CryptoInfoBuffer));
  905     CryptoInfoBufferInUse = FALSE;
  906 
  907 #endif // TC_WINDOWS_BOOT
  908 }
  909 
  910 
  911 #ifndef TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
  912 
  913 
  914 
  915 // EncryptBuffer
  916 //
  917 // buf:  data to be encrypted; the start of the buffer is assumed to be aligned with the start of a data unit.
  918 // len:  number of bytes to encrypt; must be divisible by the block size (for cascaded ciphers, divisible 
  919 //       by the largest block size used within the cascade)
  920 void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
  921 {
  922     switch (cryptoInfo->mode)
  923     {
  924     case XTS:
  925         {
  926             unsigned __int8 *ks = cryptoInfo->ks;
  927             unsigned __int8 *ks2 = cryptoInfo->ks2;
  928             UINT64_STRUCT dataUnitNo;
  929             int cipher;
  930 
  931             // When encrypting/decrypting a buffer (typically a volume header) the sequential number
  932             // of the first XTS data unit in the buffer is always 0 and the start of the buffer is
  933             // always assumed to be aligned with the start of a data unit.
  934             dataUnitNo.LowPart = 0;
  935             dataUnitNo.HighPart = 0;
  936 
  937             for (cipher = EAGetFirstCipher (cryptoInfo->ea);
  938                 cipher != 0;
  939                 cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
  940             {
  941                 EncryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
  942 
  943                 ks += CipherGetKeyScheduleSize (cipher);
  944                 ks2 += CipherGetKeyScheduleSize (cipher);
  945             }
  946         }
  947         break;
  948 
  949     default:        
  950         // Unknown/wrong ID
  951         TC_THROW_FATAL_EXCEPTION;
  952     }
  953 }
  954 
  955 
  956 // buf:         data to be encrypted
  957 // unitNo:      sequential number of the data unit with which the buffer starts
  958 // nbrUnits:    number of data units in the buffer
  959 void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci)
  960 #if !defined(TC_WINDOWS_BOOT) && !defined(_UEFI)
  961 {
  962     EncryptionThreadPoolDoWork (EncryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci);
  963 }
  964 
  965 void EncryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
  966 #endif // !TC_WINDOWS_BOOT
  967 {
  968     int ea = ci->ea;
  969     unsigned __int8 *ks = ci->ks;
  970     unsigned __int8 *ks2 = ci->ks2;
  971     int cipher;
  972 
  973     switch (ci->mode)
  974     {
  975     case XTS:
  976         for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
  977         {
  978             EncryptBufferXTS (buf,
  979                 nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
  980                 structUnitNo,
  981                 0,
  982                 ks,
  983                 ks2,
  984                 cipher);
  985 
  986             ks += CipherGetKeyScheduleSize (cipher);
  987             ks2 += CipherGetKeyScheduleSize (cipher);
  988         }
  989         break;
  990 
  991     default:        
  992         // Unknown/wrong ID
  993         TC_THROW_FATAL_EXCEPTION;
  994     }
  995 }
  996 
  997 // DecryptBuffer
  998 //
  999 // buf:  data to be decrypted; the start of the buffer is assumed to be aligned with the start of a data unit.
 1000 // len:  number of bytes to decrypt; must be divisible by the block size (for cascaded ciphers, divisible 
 1001 //       by the largest block size used within the cascade)
 1002 void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
 1003 {
 1004     switch (cryptoInfo->mode)
 1005     {
 1006     case XTS:
 1007         {
 1008             unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
 1009             unsigned __int8 *ks2 = cryptoInfo->ks2 + EAGetKeyScheduleSize (cryptoInfo->ea);
 1010             UINT64_STRUCT dataUnitNo;
 1011             int cipher;
 1012 
 1013             // When encrypting/decrypting a buffer (typically a volume header) the sequential number
 1014             // of the first XTS data unit in the buffer is always 0 and the start of the buffer is
 1015             // always assumed to be aligned with the start of the data unit 0.
 1016             dataUnitNo.LowPart = 0;
 1017             dataUnitNo.HighPart = 0;
 1018 
 1019             for (cipher = EAGetLastCipher (cryptoInfo->ea);
 1020                 cipher != 0;
 1021                 cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
 1022             {
 1023                 ks -= CipherGetKeyScheduleSize (cipher);
 1024                 ks2 -= CipherGetKeyScheduleSize (cipher);
 1025 
 1026                 DecryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
 1027             }
 1028         }
 1029         break;
 1030 
 1031     default:        
 1032         // Unknown/wrong ID
 1033         TC_THROW_FATAL_EXCEPTION;
 1034     }
 1035 }
 1036 
 1037 // buf:         data to be decrypted
 1038 // unitNo:      sequential number of the data unit with which the buffer starts
 1039 // nbrUnits:    number of data units in the buffer
 1040 void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, uint32 nbrUnits, PCRYPTO_INFO ci)
 1041 #if !defined(TC_WINDOWS_BOOT) && !defined(_UEFI)
 1042 {
 1043     EncryptionThreadPoolDoWork (DecryptDataUnitsWork, buf, structUnitNo, nbrUnits, ci);
 1044 }
 1045 
 1046 void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
 1047 #endif // !TC_WINDOWS_BOOT
 1048 {
 1049     int ea = ci->ea;
 1050     unsigned __int8 *ks = ci->ks;
 1051     unsigned __int8 *ks2 = ci->ks2;
 1052     int cipher;
 1053 
 1054 
 1055     switch (ci->mode)
 1056     {
 1057     case XTS:
 1058         ks += EAGetKeyScheduleSize (ea);
 1059         ks2 += EAGetKeyScheduleSize (ea);
 1060 
 1061         for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
 1062         {
 1063             ks -= CipherGetKeyScheduleSize (cipher);
 1064             ks2 -= CipherGetKeyScheduleSize (cipher);
 1065 
 1066             DecryptBufferXTS (buf,
 1067                 nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
 1068                 structUnitNo,
 1069                 0,
 1070                 ks,
 1071                 ks2,
 1072                 cipher);
 1073         }
 1074         break;
 1075 
 1076     default:        
 1077         // Unknown/wrong ID
 1078         TC_THROW_FATAL_EXCEPTION;
 1079     }
 1080 }
 1081 
 1082 
 1083 #else // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
 1084 
 1085 
 1086 #if !defined (TC_WINDOWS_BOOT_AES) && !defined (TC_WINDOWS_BOOT_SERPENT) && !defined (TC_WINDOWS_BOOT_TWOFISH) && !defined (TC_WINDOWS_BOOT_CAMELLIA)
 1087 #error No cipher defined
 1088 #endif
 1089 
 1090 void EncipherBlock(int cipher, void *data, void *ks)
 1091 {
 1092 #ifdef TC_WINDOWS_BOOT_AES
 1093     if (IsAesHwCpuSupported())
 1094         aes_hw_cpu_encrypt ((byte *) ks, data);
 1095     else
 1096         aes_encrypt (data, data, ks); 
 1097 #elif defined (TC_WINDOWS_BOOT_SERPENT)
 1098     serpent_encrypt (data, data, ks);
 1099 #elif defined (TC_WINDOWS_BOOT_TWOFISH)
 1100     twofish_encrypt (ks, data, data);
 1101 #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
 1102     camellia_encrypt (data, data, ks);
 1103 #endif
 1104 }
 1105 
 1106 void DecipherBlock(int cipher, void *data, void *ks)
 1107 {
 1108 #ifdef TC_WINDOWS_BOOT_AES
 1109     if (IsAesHwCpuSupported())
 1110         aes_hw_cpu_decrypt ((byte *) ks + sizeof (aes_encrypt_ctx) + 14 * 16, data);
 1111     else
 1112         aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx))); 
 1113 #elif defined (TC_WINDOWS_BOOT_SERPENT)
 1114     serpent_decrypt (data, data, ks);
 1115 #elif defined (TC_WINDOWS_BOOT_TWOFISH)
 1116     twofish_decrypt (ks, data, data);
 1117 #elif defined (TC_WINDOWS_BOOT_CAMELLIA)
 1118     camellia_decrypt (data, data, ks);
 1119 #endif
 1120 }
 1121 
 1122 
 1123 #ifdef TC_WINDOWS_BOOT_AES
 1124 
 1125 int EAInit (unsigned char *key, unsigned __int8 *ks)
 1126 {
 1127     aes_init();
 1128 
 1129     if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
 1130         return ERR_CIPHER_INIT_FAILURE;
 1131     if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
 1132         return ERR_CIPHER_INIT_FAILURE;
 1133 
 1134     return ERR_SUCCESS;
 1135 }
 1136 
 1137 #endif
 1138 
 1139 
 1140 void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
 1141 {
 1142     UINT64_STRUCT dataUnitNo;
 1143     dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
 1144     EncryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
 1145 }
 1146 
 1147 void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
 1148 {
 1149     EncryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
 1150 }
 1151 
 1152 void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
 1153 {
 1154     UINT64_STRUCT dataUnitNo;
 1155     dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
 1156     DecryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
 1157 }
 1158 
 1159 void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
 1160 {
 1161     DecryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
 1162 }
 1163 
 1164 #endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
 1165 
 1166 
 1167 #if !defined (TC_WINDOWS_BOOT) || defined (TC_WINDOWS_BOOT_AES)
 1168 
 1169 static BOOL HwEncryptionDisabled = FALSE;
 1170 
 1171 BOOL IsAesHwCpuSupported ()
 1172 {
 1173 #ifdef TC_WINDOWS_BOOT_AES
 1174     static BOOL state = FALSE;
 1175     static BOOL stateValid = FALSE;
 1176 
 1177     if (!stateValid)
 1178     {
 1179         state = is_aes_hw_cpu_supported() ? TRUE : FALSE;
 1180         stateValid = TRUE;
 1181     }
 1182 
 1183     return state && !HwEncryptionDisabled;
 1184 #else
 1185     return (HasAESNI() && !HwEncryptionDisabled)? TRUE : FALSE;
 1186 #endif
 1187 }
 1188 
 1189 void EnableHwEncryption (BOOL enable)
 1190 {
 1191 #if defined (TC_WINDOWS_BOOT)
 1192     if (enable)
 1193         aes_hw_cpu_enable_sse();
 1194 #endif
 1195 
 1196     HwEncryptionDisabled = !enable;
 1197 }
 1198 
 1199 BOOL IsHwEncryptionEnabled ()
 1200 {
 1201     return !HwEncryptionDisabled;
 1202 }
 1203 
 1204 #endif // !TC_WINDOWS_BOOT