123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224 |
- // xts.h - written and placed in the public domain by Jeffrey Walton
- /// \file xts.h
- /// \brief Classes for XTS block cipher mode of operation
- /// \details XTS mode is a wide block mode defined by IEEE P1619-2008. NIST
- /// SP-800-38E approves the mode for storage devices citing IEEE 1619-2007.
- /// IEEE 1619-2007 provides both a reference implementation and test vectors.
- /// The IEEE reference implementation fails to arrive at the expected result
- /// for some test vectors.
- /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of
- /// Operation</A> on the Crypto++ wiki, <A
- /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some
- /// Blockcipher Modes of Operation</A>, <A
- /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation
- /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on
- /// Storage Devices</A>, <A
- /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A>
- /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS,
- /// inconsistent reference implementation and test vectors</A>.
- /// \since Crypto++ 8.3
- #ifndef CRYPTOPP_XTS_MODE_H
- #define CRYPTOPP_XTS_MODE_H
- #include "cryptlib.h"
- #include "secblock.h"
- #include "modes.h"
- #include "misc.h"
- /// \brief Enable XTS for wide block ciphers
- /// \details XTS is only defined for AES. The library can support wide
- /// block ciphers like Kaylna and Threefish since we know the polynomials.
- /// To enable wide block ciphers define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt>
- /// to non-zero. Note this is a library compile time define.
- /// \details There is risk involved with using XTS with wider block ciphers.
- /// According to Phillip Rogaway, "The narrow width of the underlying PRP and
- /// the poor treatment of fractional final blocks are problems."
- /// \sa <A HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf">Evaluation
- /// of Some Blockcipher Modes of Operation</A>
- /// \since Crypto++ 8.3
- #ifndef CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS
- # define CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS 0
- #endif // CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS
- NAMESPACE_BEGIN(CryptoPP)
- /// \brief XTS block cipher mode of operation default implementation
- /// \since Crypto++ 8.3
- class CRYPTOPP_NO_VTABLE XTS_ModeBase : public BlockOrientedCipherModeBase
- {
- public:
- /// \brief The algorithm name
- /// \return the algorithm name
- /// \details StaticAlgorithmName returns the algorithm's name as a static
- /// member function.
- CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName()
- {return "XTS";}
- virtual ~XTS_ModeBase() {}
- std::string AlgorithmName() const
- {return GetBlockCipher().AlgorithmName() + "/XTS";}
- std::string AlgorithmProvider() const
- {return GetBlockCipher().AlgorithmProvider();}
- size_t MinKeyLength() const
- {return GetBlockCipher().MinKeyLength()*2;}
- size_t MaxKeyLength() const
- {return GetBlockCipher().MaxKeyLength()*2;}
- size_t DefaultKeyLength() const
- {return GetBlockCipher().DefaultKeyLength()*2;}
- size_t GetValidKeyLength(size_t n) const
- {return 2*GetBlockCipher().GetValidKeyLength((n+1)/2);}
- bool IsValidKeyLength(size_t keylength) const
- {return keylength == GetValidKeyLength(keylength);}
- /// \brief Validates the key length
- /// \param length the size of the keying material, in bytes
- /// \throw InvalidKeyLength if the key length is invalid
- void ThrowIfInvalidKeyLength(size_t length);
- /// Provides the block size of the cipher
- /// \return the block size of the cipher, in bytes
- unsigned int BlockSize() const
- {return GetBlockCipher().BlockSize();}
- /// \brief Provides the input block size most efficient for this cipher
- /// \return The input block size that is most efficient for the cipher
- /// \details The base class implementation returns MandatoryBlockSize().
- /// \note Optimal input length is
- /// <tt>n * OptimalBlockSize() - GetOptimalBlockSizeUsed()</tt> for
- /// any <tt>n \> 0</tt>.
- unsigned int GetOptimalBlockSize() const
- {return GetBlockCipher().BlockSize()*ParallelBlocks;}
- unsigned int MinLastBlockSize() const
- {return GetBlockCipher().BlockSize()+1;}
- unsigned int OptimalDataAlignment() const
- {return GetBlockCipher().OptimalDataAlignment();}
- /// \brief Validates the block size
- /// \param length the block size of the cipher, in bytes
- /// \throw InvalidArgument if the block size is invalid
- /// \details If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is 0,
- /// then CIPHER must be a 16-byte block cipher. If
- /// <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is non-zero then
- /// CIPHER can be 16, 32, 64, or 128-byte block cipher.
- void ThrowIfInvalidBlockSize(size_t length);
- void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms = g_nullNameValuePairs);
- IV_Requirement IVRequirement() const {return UNIQUE_IV;}
- void Resynchronize(const byte *iv, int ivLength=-1);
- void ProcessData(byte *outString, const byte *inString, size_t length);
- size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength);
- /// \brief Resynchronize the cipher
- /// \param sector a 64-bit sector number
- /// \param order the endian order the word should be written
- /// \details The Resynchronize() overload was provided for API
- /// compatibility with the IEEE P1619 paper.
- void Resynchronize(word64 sector, ByteOrder order=BIG_ENDIAN_ORDER);
- protected:
- virtual void ResizeBuffers();
- inline size_t ProcessLastPlainBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength);
- inline size_t ProcessLastCipherBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength);
- virtual BlockCipher& AccessBlockCipher() = 0;
- virtual BlockCipher& AccessTweakCipher() = 0;
- const BlockCipher& GetBlockCipher() const
- {return const_cast<XTS_ModeBase*>(this)->AccessBlockCipher();}
- const BlockCipher& GetTweakCipher() const
- {return const_cast<XTS_ModeBase*>(this)->AccessTweakCipher();}
- // Buffers are sized based on ParallelBlocks
- AlignedSecByteBlock m_xregister;
- AlignedSecByteBlock m_xworkspace;
- // Intel lacks the SSE registers to run 8 or 12 parallel blocks.
- // Do not change this value after compiling. It has no effect.
- #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86
- enum {ParallelBlocks = 4};
- #else
- enum {ParallelBlocks = 12};
- #endif
- };
- /// \brief XTS block cipher mode of operation implementation
- /// \tparam CIPHER BlockCipher derived class or type
- /// \details XTS_Final() provides access to CIPHER in base class XTS_ModeBase()
- /// through an interface. AccessBlockCipher() and AccessTweakCipher() allow
- /// the XTS_ModeBase() base class to access the user's block cipher without
- /// recompiling the library.
- /// \details If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is 0, then CIPHER must
- /// be a 16-byte block cipher. If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is
- /// non-zero then CIPHER can be 16, 32, 64, or 128-byte block cipher.
- /// There is risk involved with using XTS with wider block ciphers.
- /// According to Phillip Rogaway, "The narrow width of the underlying PRP and
- /// the poor treatment of fractional final blocks are problems." To enable
- /// wide block cipher support define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> to
- /// non-zero.
- /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of
- /// Operation</A> on the Crypto++ wiki, <A
- /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some
- /// Blockcipher Modes of Operation</A>, <A
- /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation
- /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on
- /// Storage Devices</A>, <A
- /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A>
- /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS,
- /// inconsistent reference implementation and test vectors</A>.
- /// \since Crypto++ 8.3
- template <class CIPHER>
- class CRYPTOPP_NO_VTABLE XTS_Final : public XTS_ModeBase
- {
- protected:
- BlockCipher& AccessBlockCipher()
- {return *m_cipher;}
- BlockCipher& AccessTweakCipher()
- {return m_tweaker;}
- protected:
- typename CIPHER::Encryption m_tweaker;
- };
- /// \brief XTS block cipher mode of operation
- /// \tparam CIPHER BlockCipher derived class or type
- /// \details XTS mode is a wide block mode defined by IEEE P1619-2008. NIST
- /// SP-800-38E approves the mode for storage devices citing IEEE 1619-2007.
- /// IEEE 1619-2007 provides both a reference implementation and test vectors.
- /// The IEEE reference implementation fails to arrive at the expected result
- /// for some test vectors.
- /// \details XTS is only defined for AES. The library can support wide
- /// block ciphers like Kaylna and Threefish since we know the polynomials.
- /// There is risk involved with using XTS with wider block ciphers.
- /// According to Phillip Rogaway, "The narrow width of the underlying PRP and
- /// the poor treatment of fractional final blocks are problems." To enable
- /// wide block cipher support define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> to
- /// non-zero.
- /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of
- /// Operation</A> on the Crypto++ wiki, <A
- /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some
- /// Blockcipher Modes of Operation</A>, <A
- /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation
- /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on
- /// Storage Devices</A>, <A
- /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A>
- /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS,
- /// inconsistent reference implementation and test vectors</A>.
- /// \since Crypto++ 8.3
- template <class CIPHER>
- struct XTS : public CipherModeDocumentation
- {
- typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, XTS_Final<CIPHER> > Encryption;
- typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Decryption, XTS_Final<CIPHER> > Decryption;
- };
- // C++03 lacks the mechanics to typedef a template
- #define XTS_Mode XTS
- NAMESPACE_END
- #endif // CRYPTOPP_XTS_MODE_H
|