void DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, TC_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) #endif // !TC_WINDOWS_BOOT { int ea = ci->ea; unsigned __int8 *ks = ci->ks; unsigned __int8 *ks2 = ci->ks2; int cipher; 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; default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } }
// DecryptBuffer // // buf: data to be decrypted; the start of the buffer is assumed to be aligned with the start of a data unit. // 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 assumed to be 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; default: // Unknown/wrong ID TC_THROW_FATAL_EXCEPTION; } }
void EncryptionModeXTS::DecryptBuffer (byte *data, uint64 length, uint64 startDataUnitNo) const { if_debug (ValidateState()); CipherList::const_iterator iSecondaryCipher = SecondaryCiphers.end(); for (CipherList::const_reverse_iterator iCipher = Ciphers.rbegin(); iCipher != Ciphers.rend(); ++iCipher) { --iSecondaryCipher; DecryptBufferXTS (**iCipher, **iSecondaryCipher, data, length, startDataUnitNo, 0); } assert (iSecondaryCipher == SecondaryCiphers.begin()); }
void DecryptDataUnits (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, GST_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) { DecryptBufferXTS (buf, nbrUnits * ENCRYPTION_DATA_UNIT_SIZE, structUnitNo, 0, ci->ks, ci->ks2, 1); }
void DecryptBuffer (unsigned __int8 *buf, GST_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 DecryptDataUnitsCurrentThread (unsigned __int8 *buf, const UINT64_STRUCT *structUnitNo, GST_LARGEST_COMPILER_UINT nbrUnits, PCRYPTO_INFO ci) #endif // !GST_WINDOWS_BOOT { int ea = ci->ea; unsigned __int8 *ks = ci->ks; unsigned __int8 *ks2 = ci->ks2; int cipher; #ifndef GST_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 GST_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 GST_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: GST_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 GST_NO_COMPILER_INT64 default: // Unknown/wrong ID GST_THROW_FATAL_EXCEPTION; } }
// DecryptBuffer // // buf: data to be decrypted; the start of the buffer is assumed to be aligned with the start of a data unit. // 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, GST_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 assumed to be 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 GST_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: GST_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 GST_NO_COMPILER_INT64 default: // Unknown/wrong ID GST_THROW_FATAL_EXCEPTION; } }