diff options
Diffstat (limited to 'src/Volume/Cipher.cpp')
-rw-r--r-- | src/Volume/Cipher.cpp | 116 |
1 files changed, 85 insertions, 31 deletions
diff --git a/src/Volume/Cipher.cpp b/src/Volume/Cipher.cpp index 8c6ce390..de240544 100644 --- a/src/Volume/Cipher.cpp +++ b/src/Volume/Cipher.cpp @@ -22,448 +22,502 @@ # include "Crypto/Aes_hw_cpu.h" #endif extern "C" int IsAesHwCpuSupported () { #ifdef TC_AES_HW_CPU static bool state = false; static bool stateValid = false; if (!stateValid) { state = HasAESNI() ? true : false; stateValid = true; } return state && VeraCrypt::Cipher::IsHwSupportEnabled(); #else return false; #endif } namespace VeraCrypt { Cipher::Cipher () : Initialized (false) { } Cipher::~Cipher () { } - void Cipher::DecryptBlock (byte *data) const + void Cipher::DecryptBlock (uint8 *data) const { if (!Initialized) throw NotInitialized (SRC_POS); Decrypt (data); } - void Cipher::DecryptBlocks (byte *data, size_t blockCount) const + void Cipher::DecryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); while (blockCount-- > 0) { Decrypt (data); data += GetBlockSize(); } } - void Cipher::EncryptBlock (byte *data) const + void Cipher::EncryptBlock (uint8 *data) const { if (!Initialized) throw NotInitialized (SRC_POS); Encrypt (data); } - void Cipher::EncryptBlocks (byte *data, size_t blockCount) const + void Cipher::EncryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); while (blockCount-- > 0) { Encrypt (data); data += GetBlockSize(); } } CipherList Cipher::GetAvailableCiphers () { CipherList l; l.push_back (shared_ptr <Cipher> (new CipherAES ())); + #ifndef WOLFCRYPT_BACKEND l.push_back (shared_ptr <Cipher> (new CipherSerpent ())); l.push_back (shared_ptr <Cipher> (new CipherTwofish ())); l.push_back (shared_ptr <Cipher> (new CipherCamellia ())); l.push_back (shared_ptr <Cipher> (new CipherKuznyechik ())); - + #endif return l; } void Cipher::SetKey (const ConstBufferPtr &key) { if (key.Size() != GetKeySize ()) throw ParameterIncorrect (SRC_POS); if (!Initialized) ScheduledKey.Allocate (GetScheduledKeySize ()); SetCipherKey (key); Key.CopyFrom (key); Initialized = true; } + #ifdef WOLFCRYPT_BACKEND + void Cipher::SetKeyXTS (const ConstBufferPtr &key) + { + if (key.Size() != GetKeySize ()) + throw ParameterIncorrect (SRC_POS); + + if (!Initialized) + ScheduledKey.Allocate (GetScheduledKeySize ()); + + SetCipherKeyXTS (key); + Key.CopyFrom (key); + Initialized = true; + } + + void Cipher::EncryptBlockXTS (uint8 *data, uint64 length, uint64 startDataUnitNo) const + { + if (!Initialized) + throw NotInitialized (SRC_POS); + + EncryptXTS (data, length, startDataUnitNo); + } + + void Cipher::DecryptBlockXTS (uint8 *data, uint64 length, uint64 startDataUnitNo) const + { + if (!Initialized) + throw NotInitialized (SRC_POS); + + DecryptXTS (data, length, startDataUnitNo); + } + #endif + #define TC_EXCEPTION(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) #undef TC_EXCEPTION_NODECL #define TC_EXCEPTION_NODECL(TYPE) TC_SERIALIZER_FACTORY_ADD(TYPE) TC_SERIALIZER_FACTORY_ADD_EXCEPTION_SET (CipherException); // AES - void CipherAES::Decrypt (byte *data) const + void CipherAES::Decrypt (uint8 *data) const { #ifdef TC_AES_HW_CPU if (IsHwSupportAvailable()) aes_hw_cpu_decrypt (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx), data); else #endif aes_decrypt (data, data, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx))); } - void CipherAES::DecryptBlocks (byte *data, size_t blockCount) const + void CipherAES::DecryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #ifdef TC_AES_HW_CPU if ((blockCount & (32 - 1)) == 0 && IsHwSupportAvailable()) { while (blockCount > 0) { aes_hw_cpu_decrypt_32_blocks (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx), data); data += 32 * GetBlockSize(); blockCount -= 32; } } else #endif Cipher::DecryptBlocks (data, blockCount); } - void CipherAES::Encrypt (byte *data) const + void CipherAES::Encrypt (uint8 *data) const { #ifdef TC_AES_HW_CPU if (IsHwSupportAvailable()) aes_hw_cpu_encrypt (ScheduledKey.Ptr(), data); else #endif aes_encrypt (data, data, (aes_encrypt_ctx *) ScheduledKey.Ptr()); } - void CipherAES::EncryptBlocks (byte *data, size_t blockCount) const + void CipherAES::EncryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #ifdef TC_AES_HW_CPU if ((blockCount & (32 - 1)) == 0 && IsHwSupportAvailable()) { while (blockCount > 0) { aes_hw_cpu_encrypt_32_blocks (ScheduledKey.Ptr(), data); data += 32 * GetBlockSize(); blockCount -= 32; } } else #endif Cipher::EncryptBlocks (data, blockCount); } + #ifdef WOLFCRYPT_BACKEND + void CipherAES::EncryptXTS (uint8 *data, uint64 length, uint64 startDataUnitNo) const + { + xts_encrypt (data, data, length, startDataUnitNo, (aes_encrypt_ctx *) ScheduledKey.Ptr()); + } + + void CipherAES::DecryptXTS (uint8 *data, uint64 length, uint64 startDataUnitNo) const + { + xts_decrypt (data, data, length, startDataUnitNo, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx))); + } + + void CipherAES::SetCipherKeyXTS (const uint8 *key) + { + if (xts_encrypt_key256 (key, (aes_encrypt_ctx *) ScheduledKey.Ptr()) != EXIT_SUCCESS) + throw CipherInitError (SRC_POS); + + if (xts_decrypt_key256 (key, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS) + throw CipherInitError (SRC_POS); + } + #endif size_t CipherAES::GetScheduledKeySize () const { return sizeof(aes_encrypt_ctx) + sizeof(aes_decrypt_ctx); } bool CipherAES::IsHwSupportAvailable () const { #ifdef TC_AES_HW_CPU static bool state = false; static bool stateValid = false; if (!stateValid) { state = HasAESNI() ? true : false; stateValid = true; } return state && HwSupportEnabled; #else return false; #endif } - void CipherAES::SetCipherKey (const byte *key) + void CipherAES::SetCipherKey (const uint8 *key) { if (aes_encrypt_key256 (key, (aes_encrypt_ctx *) ScheduledKey.Ptr()) != EXIT_SUCCESS) throw CipherInitError (SRC_POS); if (aes_decrypt_key256 (key, (aes_decrypt_ctx *) (ScheduledKey.Ptr() + sizeof (aes_encrypt_ctx))) != EXIT_SUCCESS) throw CipherInitError (SRC_POS); } + #ifndef WOLFCRYPT_BACKEND // Serpent - void CipherSerpent::Decrypt (byte *data) const + void CipherSerpent::Decrypt (uint8 *data) const { serpent_decrypt (data, data, ScheduledKey); } - void CipherSerpent::Encrypt (byte *data) const + void CipherSerpent::Encrypt (uint8 *data) const { serpent_encrypt (data, data, ScheduledKey); } size_t CipherSerpent::GetScheduledKeySize () const { return 140*4; } - void CipherSerpent::SetCipherKey (const byte *key) + void CipherSerpent::SetCipherKey (const uint8 *key) { serpent_set_key (key, ScheduledKey); } - void CipherSerpent::EncryptBlocks (byte *data, size_t blockCount) const + void CipherSerpent::EncryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined(CRYPTOPP_DISABLE_ASM) if ((blockCount >= 4) && IsHwSupportAvailable()) { serpent_encrypt_blocks (data, data, blockCount, ScheduledKey.Ptr()); } else #endif Cipher::EncryptBlocks (data, blockCount); } - void CipherSerpent::DecryptBlocks (byte *data, size_t blockCount) const + void CipherSerpent::DecryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE && !defined(CRYPTOPP_DISABLE_ASM) if ((blockCount >= 4) && IsHwSupportAvailable()) { serpent_decrypt_blocks (data, data, blockCount, ScheduledKey.Ptr()); } else #endif Cipher::DecryptBlocks (data, blockCount); } bool CipherSerpent::IsHwSupportAvailable () const { #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE static bool state = false; static bool stateValid = false; if (!stateValid) { state = HasSSE2() ? true : false; stateValid = true; } return state; #else return false; #endif } // Twofish - void CipherTwofish::Decrypt (byte *data) const + void CipherTwofish::Decrypt (uint8 *data) const { twofish_decrypt ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *)data, (unsigned int *)data); } - void CipherTwofish::Encrypt (byte *data) const + void CipherTwofish::Encrypt (uint8 *data) const { twofish_encrypt ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *)data, (unsigned int *)data); } size_t CipherTwofish::GetScheduledKeySize () const { return TWOFISH_KS; } - void CipherTwofish::SetCipherKey (const byte *key) + void CipherTwofish::SetCipherKey (const uint8 *key) { twofish_set_key ((TwofishInstance *) ScheduledKey.Ptr(), (unsigned int *) key); } - void CipherTwofish::EncryptBlocks (byte *data, size_t blockCount) const + void CipherTwofish::EncryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) twofish_encrypt_blocks ( (TwofishInstance *) ScheduledKey.Ptr(), data, data, blockCount); #else Cipher::EncryptBlocks (data, blockCount); #endif } - void CipherTwofish::DecryptBlocks (byte *data, size_t blockCount) const + void CipherTwofish::DecryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) twofish_decrypt_blocks ( (TwofishInstance *) ScheduledKey.Ptr(), data, data, blockCount); #else Cipher::DecryptBlocks (data, blockCount); #endif } bool CipherTwofish::IsHwSupportAvailable () const { #if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) return true; #else return false; #endif } // Camellia - void CipherCamellia::Decrypt (byte *data) const + void CipherCamellia::Decrypt (uint8 *data) const { camellia_decrypt (data, data, ScheduledKey.Ptr()); } - void CipherCamellia::Encrypt (byte *data) const + void CipherCamellia::Encrypt (uint8 *data) const { camellia_encrypt (data, data, ScheduledKey.Ptr()); } size_t CipherCamellia::GetScheduledKeySize () const { return CAMELLIA_KS; } - void CipherCamellia::SetCipherKey (const byte *key) + void CipherCamellia::SetCipherKey (const uint8 *key) { camellia_set_key (key, ScheduledKey.Ptr()); } - void CipherCamellia::EncryptBlocks (byte *data, size_t blockCount) const + void CipherCamellia::EncryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) camellia_encrypt_blocks ( ScheduledKey.Ptr(), data, data, blockCount); #else Cipher::EncryptBlocks (data, blockCount); #endif } - void CipherCamellia::DecryptBlocks (byte *data, size_t blockCount) const + void CipherCamellia::DecryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) camellia_decrypt_blocks ( ScheduledKey.Ptr(), data, data, blockCount); #else Cipher::DecryptBlocks (data, blockCount); #endif } bool CipherCamellia::IsHwSupportAvailable () const { #if CRYPTOPP_BOOL_X64 && !defined(CRYPTOPP_DISABLE_ASM) return true; #else return false; #endif } // Kuznyechik - void CipherKuznyechik::Decrypt (byte *data) const + void CipherKuznyechik::Decrypt (uint8 *data) const { kuznyechik_decrypt_block (data, data, (kuznyechik_kds *) ScheduledKey.Ptr()); } - void CipherKuznyechik::Encrypt (byte *data) const + void CipherKuznyechik::Encrypt (uint8 *data) const { kuznyechik_encrypt_block (data, data, (kuznyechik_kds *) ScheduledKey.Ptr()); } size_t CipherKuznyechik::GetScheduledKeySize () const { return KUZNYECHIK_KS; } - void CipherKuznyechik::SetCipherKey (const byte *key) + void CipherKuznyechik::SetCipherKey (const uint8 *key) { kuznyechik_set_key (key, (kuznyechik_kds *) ScheduledKey.Ptr()); } - void CipherKuznyechik::EncryptBlocks (byte *data, size_t blockCount) const + void CipherKuznyechik::EncryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE if ((blockCount >= 4) && IsHwSupportAvailable()) { kuznyechik_encrypt_blocks (data, data, blockCount, (kuznyechik_kds *) ScheduledKey.Ptr()); } else #endif Cipher::EncryptBlocks (data, blockCount); } - void CipherKuznyechik::DecryptBlocks (byte *data, size_t blockCount) const + void CipherKuznyechik::DecryptBlocks (uint8 *data, size_t blockCount) const { if (!Initialized) throw NotInitialized (SRC_POS); #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE if ((blockCount >= 4) && IsHwSupportAvailable()) { kuznyechik_decrypt_blocks (data, data, blockCount, (kuznyechik_kds *) ScheduledKey.Ptr()); } else #endif Cipher::DecryptBlocks (data, blockCount); } bool CipherKuznyechik::IsHwSupportAvailable () const { #if CRYPTOPP_BOOL_SSE2_INTRINSICS_AVAILABLE static bool state = false; static bool stateValid = false; if (!stateValid) { state = HasSSE2() ? true : false; stateValid = true; } return state; #else return false; #endif } - bool Cipher::HwSupportEnabled = true; + #endif + bool Cipher::HwSupportEnabled = true; } |