📄 crypto.c
字号:
// ciphers divisible by the largest block size used within the cascade)
void EncryptBuffer (unsigned __int8 *buf,
TC_LARGEST_COMPILER_UINT len,
PCRYPTO_INFO cryptoInfo)
{
switch (cryptoInfo->mode)
{
case XTS:
{
unsigned __int8 *ks = cryptoInfo->ks;
unsigned __int8 *ks2 = cryptoInfo->ks2;
UINT64_STRUCT dataUnitNo;
int cipher;
// When encrypting/decrypting a buffer (typically a volume header) the sequential number
// of the first XTS data unit in the buffer is always 0 and the start of the buffer is
// always considered aligned with the start of a data unit.
dataUnitNo.LowPart = 0;
dataUnitNo.HighPart = 0;
for (cipher = EAGetFirstCipher (cryptoInfo->ea);
cipher != 0;
cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
{
EncryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
ks += CipherGetKeyScheduleSize (cipher);
ks2 += CipherGetKeyScheduleSize (cipher);
}
}
break;
#ifndef TC_NO_COMPILER_INT64
case LRW:
/* Deprecated/legacy */
switch (CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea)))
{
case 8:
EncryptBufferLRW64 ((unsigned __int8 *)buf, (unsigned __int64) len, 1, cryptoInfo);
break;
case 16:
EncryptBufferLRW128 ((unsigned __int8 *)buf, (unsigned __int64) len, 1, cryptoInfo);
break;
default:
TC_THROW_FATAL_EXCEPTION;
}
break;
case CBC:
case INNER_CBC:
{
/* Deprecated/legacy */
unsigned __int8 *ks = cryptoInfo->ks;
int cipher;
for (cipher = EAGetFirstCipher (cryptoInfo->ea);
cipher != 0;
cipher = EAGetNextCipher (cryptoInfo->ea, cipher))
{
EncryptBufferCBC ((unsigned __int32 *) buf,
(unsigned int) len,
ks,
(unsigned __int32 *) cryptoInfo->k2,
(unsigned __int32 *) &cryptoInfo->k2[8],
0,
cipher);
ks += CipherGetKeyScheduleSize (cipher);
}
}
break;
case OUTER_CBC:
/* Deprecated/legacy */
EncryptBufferCBC ((unsigned __int32 *) buf,
(unsigned int) len,
cryptoInfo->ks,
(unsigned __int32 *) cryptoInfo->k2,
(unsigned __int32 *) &cryptoInfo->k2[8],
cryptoInfo->ea,
0);
break;
#endif // #ifndef TC_NO_COMPILER_INT64
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
}
}
#ifndef TC_NO_COMPILER_INT64
// Converts a data unit number to the index of the first LRW block in the data unit.
// Note that the maximum supported volume size is 8589934592 GB (i.e., 2^63 bytes).
unsigned __int64 DataUnit2LRWIndex (unsigned __int64 dataUnit, int blockSize, PCRYPTO_INFO ci)
{
/* Deprecated/legacy */
if (ci->hiddenVolume)
dataUnit -= ci->hiddenVolumeOffset / ENCRYPTION_DATA_UNIT_SIZE;
else
dataUnit -= HEADER_SIZE / ENCRYPTION_DATA_UNIT_SIZE; // Compensate for the volume header size
switch (blockSize)
{
case 8:
return (dataUnit << 6) | 1;
case 16:
return (dataUnit << 5) | 1;
default:
TC_THROW_FATAL_EXCEPTION;
}
return 0;
}
#endif // #ifndef TC_NO_COMPILER_INT64
// buf: data to be encrypted
// unitNo: sequential number of the data unit with which the buffer starts
// nbrUnits: number of data units in the buffer
void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
int ea = ci->ea;
unsigned __int8 *ks = ci->ks;
unsigned __int8 *ks2 = ci->ks2;
int cipher;
#ifndef TC_NO_COMPILER_INT64
void *iv = ci->k2; // Deprecated/legacy
unsigned __int64 unitNo = structUnitNo->Value;
unsigned __int64 *iv64 = (unsigned __int64 *) iv; // Deprecated/legacy
unsigned __int32 sectorIV[4]; // Deprecated/legacy
unsigned __int32 secWhitening[2]; // Deprecated/legacy
#endif
switch (ci->mode)
{
case XTS:
for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
{
EncryptBufferXTS (buf,
nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
structUnitNo,
0,
ks,
ks2,
cipher);
ks += CipherGetKeyScheduleSize (cipher);
ks2 += CipherGetKeyScheduleSize (cipher);
}
break;
#ifndef TC_NO_COMPILER_INT64
case LRW:
/* Deprecated/legacy */
switch (CipherGetBlockSize (EAGetFirstCipher (ea)))
{
case 8:
EncryptBufferLRW64 (buf,
(unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
DataUnit2LRWIndex (unitNo, 8, ci),
ci);
break;
case 16:
EncryptBufferLRW128 (buf,
(unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
DataUnit2LRWIndex (unitNo, 16, ci),
ci);
break;
default:
TC_THROW_FATAL_EXCEPTION;
}
break;
case CBC:
case INNER_CBC:
/* Deprecated/legacy */
while (nbrUnits--)
{
for (cipher = EAGetFirstCipher (ea); cipher != 0; cipher = EAGetNextCipher (ea, cipher))
{
InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);
EncryptBufferCBC ((unsigned __int32 *) buf,
ENCRYPTION_DATA_UNIT_SIZE,
ks,
sectorIV,
secWhitening,
0,
cipher);
ks += CipherGetKeyScheduleSize (cipher);
}
ks -= EAGetKeyScheduleSize (ea);
buf += ENCRYPTION_DATA_UNIT_SIZE;
unitNo++;
}
break;
case OUTER_CBC:
/* Deprecated/legacy */
while (nbrUnits--)
{
InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);
EncryptBufferCBC ((unsigned __int32 *) buf,
ENCRYPTION_DATA_UNIT_SIZE,
ks,
sectorIV,
secWhitening,
ea,
0);
buf += ENCRYPTION_DATA_UNIT_SIZE;
unitNo++;
}
break;
#endif // #ifndef TC_NO_COMPILER_INT64
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
}
}
// DecryptBuffer
//
// buf: data to be decrypted
// len: number of bytes to decrypt; must be divisible by the block size (for cascaded
// ciphers divisible by the largest block size used within the cascade)
void DecryptBuffer (unsigned __int8 *buf,
TC_LARGEST_COMPILER_UINT len,
PCRYPTO_INFO cryptoInfo)
{
switch (cryptoInfo->mode)
{
case XTS:
{
unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
unsigned __int8 *ks2 = cryptoInfo->ks2 + EAGetKeyScheduleSize (cryptoInfo->ea);
UINT64_STRUCT dataUnitNo;
int cipher;
// When encrypting/decrypting a buffer (typically a volume header) the sequential number
// of the first XTS data unit in the buffer is always 0 and the start of the buffer is
// always considered aligned with the start of the data unit 0.
dataUnitNo.LowPart = 0;
dataUnitNo.HighPart = 0;
for (cipher = EAGetLastCipher (cryptoInfo->ea);
cipher != 0;
cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
{
ks -= CipherGetKeyScheduleSize (cipher);
ks2 -= CipherGetKeyScheduleSize (cipher);
DecryptBufferXTS (buf, len, &dataUnitNo, 0, ks, ks2, cipher);
}
}
break;
#ifndef TC_NO_COMPILER_INT64
case LRW:
/* Deprecated/legacy */
switch (CipherGetBlockSize (EAGetFirstCipher (cryptoInfo->ea)))
{
case 8:
DecryptBufferLRW64 (buf, (unsigned __int64) len, 1, cryptoInfo);
break;
case 16:
DecryptBufferLRW128 (buf, (unsigned __int64) len, 1, cryptoInfo);
break;
default:
TC_THROW_FATAL_EXCEPTION;
}
break;
case CBC:
case INNER_CBC:
{
/* Deprecated/legacy */
unsigned __int8 *ks = cryptoInfo->ks + EAGetKeyScheduleSize (cryptoInfo->ea);
int cipher;
for (cipher = EAGetLastCipher (cryptoInfo->ea);
cipher != 0;
cipher = EAGetPreviousCipher (cryptoInfo->ea, cipher))
{
ks -= CipherGetKeyScheduleSize (cipher);
DecryptBufferCBC ((unsigned __int32 *) buf,
(unsigned int) len,
ks,
(unsigned __int32 *) cryptoInfo->k2,
(unsigned __int32 *) &cryptoInfo->k2[8],
0,
cipher);
}
}
break;
case OUTER_CBC:
/* Deprecated/legacy */
DecryptBufferCBC ((unsigned __int32 *) buf,
(unsigned int) len,
cryptoInfo->ks,
(unsigned __int32 *) cryptoInfo->k2,
(unsigned __int32 *) &cryptoInfo->k2[8],
cryptoInfo->ea,
0);
break;
#endif // #ifndef TC_NO_COMPILER_INT64
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
}
}
// buf: data to be decrypted
// unitNo: sequential number of the data unit with which the buffer starts
// nbrUnits: number of data units in the buffer
void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
int ea = ci->ea;
unsigned __int8 *ks = ci->ks;
unsigned __int8 *ks2 = ci->ks2;
int cipher;
#ifndef TC_NO_COMPILER_INT64
void *iv = ci->k2; // Deprecated/legacy
unsigned __int64 unitNo = structUnitNo->Value;
unsigned __int64 *iv64 = (unsigned __int64 *) iv; // Deprecated/legacy
unsigned __int32 sectorIV[4]; // Deprecated/legacy
unsigned __int32 secWhitening[2]; // Deprecated/legacy
#endif // #ifndef TC_NO_COMPILER_INT64
switch (ci->mode)
{
case XTS:
ks += EAGetKeyScheduleSize (ea);
ks2 += EAGetKeyScheduleSize (ea);
for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
{
ks -= CipherGetKeyScheduleSize (cipher);
ks2 -= CipherGetKeyScheduleSize (cipher);
DecryptBufferXTS (buf,
nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
structUnitNo,
0,
ks,
ks2,
cipher);
}
break;
#ifndef TC_NO_COMPILER_INT64
case LRW:
/* Deprecated/legacy */
switch (CipherGetBlockSize (EAGetFirstCipher (ea)))
{
case 8:
DecryptBufferLRW64 (buf,
(unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
DataUnit2LRWIndex (unitNo, 8, ci),
ci);
break;
case 16:
DecryptBufferLRW128 (buf,
(unsigned __int64) nbrUnits * ENCRYPTION_DATA_UNIT_SIZE,
DataUnit2LRWIndex (unitNo, 16, ci),
ci);
break;
default:
TC_THROW_FATAL_EXCEPTION;
}
break;
case CBC:
case INNER_CBC:
/* Deprecated/legacy */
while (nbrUnits--)
{
ks += EAGetKeyScheduleSize (ea);
for (cipher = EAGetLastCipher (ea); cipher != 0; cipher = EAGetPreviousCipher (ea, cipher))
{
InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (cipher), sectorIV, iv64, secWhitening);
ks -= CipherGetKeyScheduleSize (cipher);
DecryptBufferCBC ((unsigned __int32 *) buf,
ENCRYPTION_DATA_UNIT_SIZE,
ks,
sectorIV,
secWhitening,
0,
cipher);
}
buf += ENCRYPTION_DATA_UNIT_SIZE;
unitNo++;
}
break;
case OUTER_CBC:
/* Deprecated/legacy */
while (nbrUnits--)
{
InitSectorIVAndWhitening (unitNo, CipherGetBlockSize (EAGetFirstCipher (ea)), sectorIV, iv64, secWhitening);
DecryptBufferCBC ((unsigned __int32 *) buf,
ENCRYPTION_DATA_UNIT_SIZE,
ks,
sectorIV,
secWhitening,
ea,
0);
buf += ENCRYPTION_DATA_UNIT_SIZE;
unitNo++;
}
break;
#endif // #ifndef TC_NO_COMPILER_INT64
default:
// Unknown/wrong ID
TC_THROW_FATAL_EXCEPTION;
}
}
// Returns the maximum number of bytes necessary to be generated by the PBKDF2 (PKCS #5)
int GetMaxPkcs5OutSize (void)
{
int size = 32;
#ifndef max
#define max(a,b) (((a) > (b)) ? (a) : (b))
#endif
size = max (size, EAGetLargestKeyForMode (XTS) * 2); // Sizes of primary + secondary keys
#ifndef TC_WINDOWS_BOOT
size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (LRW)); // Deprecated/legacy
size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (CBC)); // Deprecated/legacy
size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (OUTER_CBC)); // Deprecated/legacy
size = max (size, LEGACY_VOL_IV_SIZE + EAGetLargestKeyForMode (INNER_CBC)); // Deprecated/legacy
#endif
return size;
}
#else // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
#if !defined (TC_WINDOWS_BOOT_AES) && !defined (TC_WINDOWS_BOOT_SERPENT) && !defined (TC_WINDOWS_BOOT_TWOFISH)
#error No cipher defined
#endif
void EncipherBlock(int cipher, void *data, void *ks)
{
#ifdef TC_WINDOWS_BOOT_AES
aes_encrypt (data, data, ks);
#elif defined (TC_WINDOWS_BOOT_SERPENT)
serpent_encrypt (data, data, ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
twofish_encrypt (ks, data, data);
#endif
}
void DecipherBlock(int cipher, void *data, void *ks)
{
#ifdef TC_WINDOWS_BOOT_AES
aes_decrypt (data, data, (aes_decrypt_ctx *) ((byte *) ks + sizeof(aes_encrypt_ctx)));
#elif defined (TC_WINDOWS_BOOT_SERPENT)
serpent_decrypt (data, data, ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
twofish_decrypt (ks, data, data);
#endif
}
int EAGetFirst ()
{
return 1;
}
int EAGetNext (int previousEA)
{
return 0;
}
int EAInit (int ea, unsigned char *key, unsigned __int8 *ks)
{
#ifdef TC_WINDOWS_BOOT_AES
aes_init();
if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ks) != EXIT_SUCCESS)
return ERR_CIPHER_INIT_FAILURE;
if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ks + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS)
return ERR_CIPHER_INIT_FAILURE;
#elif defined (TC_WINDOWS_BOOT_SERPENT)
serpent_set_key (key, 32 * 8, ks);
#elif defined (TC_WINDOWS_BOOT_TWOFISH)
twofish_set_key ((TwofishInstance *)ks, (const u4byte *)key, 32 * 8);
#endif
return ERR_SUCCESS;
}
int EAGetKeySize (int ea)
{
return 32;
}
int EAGetFirstCipher (int ea)
{
return 1;
}
void EncryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
{
UINT64_STRUCT dataUnitNo;
dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
EncryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
}
void EncryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
EncryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
}
void DecryptBuffer (unsigned __int8 *buf, TC_LARGEST_COMPILER_UINT len, PCRYPTO_INFO cryptoInfo)
{
UINT64_STRUCT dataUnitNo;
dataUnitNo.LowPart = 0; dataUnitNo.HighPart = 0;
DecryptBufferXTS (buf, len, &dataUnitNo, 0, cryptoInfo->ks, cryptoInfo->ks2, 1);
}
void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci)
{
DecryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1);
}
#endif // TC_WINDOWS_BOOT_SINGLE_CIPHER_MODE
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -