|
||||
File indexing completed on 2025-01-18 09:55:10
0001 // xts.h - written and placed in the public domain by Jeffrey Walton 0002 0003 /// \file xts.h 0004 /// \brief Classes for XTS block cipher mode of operation 0005 /// \details XTS mode is a wide block mode defined by IEEE P1619-2008. NIST 0006 /// SP-800-38E approves the mode for storage devices citing IEEE 1619-2007. 0007 /// IEEE 1619-2007 provides both a reference implementation and test vectors. 0008 /// The IEEE reference implementation fails to arrive at the expected result 0009 /// for some test vectors. 0010 /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of 0011 /// Operation</A> on the Crypto++ wiki, <A 0012 /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some 0013 /// Blockcipher Modes of Operation</A>, <A 0014 /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation 0015 /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on 0016 /// Storage Devices</A>, <A 0017 /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A> 0018 /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS, 0019 /// inconsistent reference implementation and test vectors</A>. 0020 /// \since Crypto++ 8.3 0021 0022 #ifndef CRYPTOPP_XTS_MODE_H 0023 #define CRYPTOPP_XTS_MODE_H 0024 0025 #include "cryptlib.h" 0026 #include "secblock.h" 0027 #include "modes.h" 0028 #include "misc.h" 0029 0030 /// \brief Enable XTS for wide block ciphers 0031 /// \details XTS is only defined for AES. The library can support wide 0032 /// block ciphers like Kaylna and Threefish since we know the polynomials. 0033 /// To enable wide block ciphers define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> 0034 /// to non-zero. Note this is a library compile time define. 0035 /// \details There is risk involved with using XTS with wider block ciphers. 0036 /// According to Phillip Rogaway, "The narrow width of the underlying PRP and 0037 /// the poor treatment of fractional final blocks are problems." 0038 /// \sa <A HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf">Evaluation 0039 /// of Some Blockcipher Modes of Operation</A> 0040 /// \since Crypto++ 8.3 0041 #ifndef CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS 0042 # define CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS 0 0043 #endif // CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS 0044 0045 NAMESPACE_BEGIN(CryptoPP) 0046 0047 /// \brief XTS block cipher mode of operation default implementation 0048 /// \since Crypto++ 8.3 0049 class CRYPTOPP_NO_VTABLE XTS_ModeBase : public BlockOrientedCipherModeBase 0050 { 0051 public: 0052 /// \brief The algorithm name 0053 /// \return the algorithm name 0054 /// \details StaticAlgorithmName returns the algorithm's name as a static 0055 /// member function. 0056 CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName() 0057 {return "XTS";} 0058 0059 virtual ~XTS_ModeBase() {} 0060 0061 std::string AlgorithmName() const 0062 {return GetBlockCipher().AlgorithmName() + "/XTS";} 0063 std::string AlgorithmProvider() const 0064 {return GetBlockCipher().AlgorithmProvider();} 0065 0066 size_t MinKeyLength() const 0067 {return GetBlockCipher().MinKeyLength()*2;} 0068 size_t MaxKeyLength() const 0069 {return GetBlockCipher().MaxKeyLength()*2;} 0070 size_t DefaultKeyLength() const 0071 {return GetBlockCipher().DefaultKeyLength()*2;} 0072 size_t GetValidKeyLength(size_t n) const 0073 {return 2*GetBlockCipher().GetValidKeyLength((n+1)/2);} 0074 bool IsValidKeyLength(size_t keylength) const 0075 {return keylength == GetValidKeyLength(keylength);} 0076 0077 /// \brief Validates the key length 0078 /// \param length the size of the keying material, in bytes 0079 /// \throw InvalidKeyLength if the key length is invalid 0080 void ThrowIfInvalidKeyLength(size_t length); 0081 0082 /// Provides the block size of the cipher 0083 /// \return the block size of the cipher, in bytes 0084 unsigned int BlockSize() const 0085 {return GetBlockCipher().BlockSize();} 0086 0087 /// \brief Provides the input block size most efficient for this cipher 0088 /// \return The input block size that is most efficient for the cipher 0089 /// \details The base class implementation returns MandatoryBlockSize(). 0090 /// \note Optimal input length is 0091 /// <tt>n * OptimalBlockSize() - GetOptimalBlockSizeUsed()</tt> for 0092 /// any <tt>n \> 0</tt>. 0093 unsigned int GetOptimalBlockSize() const 0094 {return GetBlockCipher().BlockSize()*ParallelBlocks;} 0095 unsigned int MinLastBlockSize() const 0096 {return GetBlockCipher().BlockSize()+1;} 0097 unsigned int OptimalDataAlignment() const 0098 {return GetBlockCipher().OptimalDataAlignment();} 0099 0100 /// \brief Validates the block size 0101 /// \param length the block size of the cipher, in bytes 0102 /// \throw InvalidArgument if the block size is invalid 0103 /// \details If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is 0, 0104 /// then CIPHER must be a 16-byte block cipher. If 0105 /// <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is non-zero then 0106 /// CIPHER can be 16, 32, 64, or 128-byte block cipher. 0107 void ThrowIfInvalidBlockSize(size_t length); 0108 0109 void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs); 0110 IV_Requirement IVRequirement() const {return UNIQUE_IV;} 0111 void Resynchronize(const byte *iv, int ivLength=-1); 0112 void ProcessData(byte *outString, const byte *inString, size_t length); 0113 size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); 0114 0115 /// \brief Resynchronize the cipher 0116 /// \param sector a 64-bit sector number 0117 /// \param order the endian order the word should be written 0118 /// \details The Resynchronize() overload was provided for API 0119 /// compatibility with the IEEE P1619 paper. 0120 void Resynchronize(word64 sector, ByteOrder order=BIG_ENDIAN_ORDER); 0121 0122 protected: 0123 virtual void ResizeBuffers(); 0124 0125 inline size_t ProcessLastPlainBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); 0126 inline size_t ProcessLastCipherBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength); 0127 0128 virtual BlockCipher& AccessBlockCipher() = 0; 0129 virtual BlockCipher& AccessTweakCipher() = 0; 0130 0131 const BlockCipher& GetBlockCipher() const 0132 {return const_cast<XTS_ModeBase*>(this)->AccessBlockCipher();} 0133 const BlockCipher& GetTweakCipher() const 0134 {return const_cast<XTS_ModeBase*>(this)->AccessTweakCipher();} 0135 0136 // Buffers are sized based on ParallelBlocks 0137 AlignedSecByteBlock m_xregister; 0138 AlignedSecByteBlock m_xworkspace; 0139 0140 // Intel lacks the SSE registers to run 8 or 12 parallel blocks. 0141 // Do not change this value after compiling. It has no effect. 0142 #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86 0143 enum {ParallelBlocks = 4}; 0144 #else 0145 enum {ParallelBlocks = 12}; 0146 #endif 0147 }; 0148 0149 /// \brief XTS block cipher mode of operation implementation 0150 /// \tparam CIPHER BlockCipher derived class or type 0151 /// \details XTS_Final() provides access to CIPHER in base class XTS_ModeBase() 0152 /// through an interface. AccessBlockCipher() and AccessTweakCipher() allow 0153 /// the XTS_ModeBase() base class to access the user's block cipher without 0154 /// recompiling the library. 0155 /// \details If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is 0, then CIPHER must 0156 /// be a 16-byte block cipher. If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is 0157 /// non-zero then CIPHER can be 16, 32, 64, or 128-byte block cipher. 0158 /// There is risk involved with using XTS with wider block ciphers. 0159 /// According to Phillip Rogaway, "The narrow width of the underlying PRP and 0160 /// the poor treatment of fractional final blocks are problems." To enable 0161 /// wide block cipher support define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> to 0162 /// non-zero. 0163 /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of 0164 /// Operation</A> on the Crypto++ wiki, <A 0165 /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some 0166 /// Blockcipher Modes of Operation</A>, <A 0167 /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation 0168 /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on 0169 /// Storage Devices</A>, <A 0170 /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A> 0171 /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS, 0172 /// inconsistent reference implementation and test vectors</A>. 0173 /// \since Crypto++ 8.3 0174 template <class CIPHER> 0175 class CRYPTOPP_NO_VTABLE XTS_Final : public XTS_ModeBase 0176 { 0177 protected: 0178 BlockCipher& AccessBlockCipher() 0179 {return *m_cipher;} 0180 BlockCipher& AccessTweakCipher() 0181 {return m_tweaker;} 0182 0183 protected: 0184 typename CIPHER::Encryption m_tweaker; 0185 }; 0186 0187 /// \brief XTS block cipher mode of operation 0188 /// \tparam CIPHER BlockCipher derived class or type 0189 /// \details XTS mode is a wide block mode defined by IEEE P1619-2008. NIST 0190 /// SP-800-38E approves the mode for storage devices citing IEEE 1619-2007. 0191 /// IEEE 1619-2007 provides both a reference implementation and test vectors. 0192 /// The IEEE reference implementation fails to arrive at the expected result 0193 /// for some test vectors. 0194 /// \details XTS is only defined for AES. The library can support wide 0195 /// block ciphers like Kaylna and Threefish since we know the polynomials. 0196 /// There is risk involved with using XTS with wider block ciphers. 0197 /// According to Phillip Rogaway, "The narrow width of the underlying PRP and 0198 /// the poor treatment of fractional final blocks are problems." To enable 0199 /// wide block cipher support define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> to 0200 /// non-zero. 0201 /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of 0202 /// Operation</A> on the Crypto++ wiki, <A 0203 /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some 0204 /// Blockcipher Modes of Operation</A>, <A 0205 /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation 0206 /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on 0207 /// Storage Devices</A>, <A 0208 /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A> 0209 /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS, 0210 /// inconsistent reference implementation and test vectors</A>. 0211 /// \since Crypto++ 8.3 0212 template <class CIPHER> 0213 struct XTS : public CipherModeDocumentation 0214 { 0215 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, XTS_Final<CIPHER> > Encryption; 0216 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Decryption, XTS_Final<CIPHER> > Decryption; 0217 }; 0218 0219 // C++03 lacks the mechanics to typedef a template 0220 #define XTS_Mode XTS 0221 0222 NAMESPACE_END 0223 0224 #endif // CRYPTOPP_XTS_MODE_H
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |