xts.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. // xts.h - written and placed in the public domain by Jeffrey Walton
  2. /// \file xts.h
  3. /// \brief Classes for XTS block cipher mode of operation
  4. /// \details XTS mode is a wide block mode defined by IEEE P1619-2008. NIST
  5. /// SP-800-38E approves the mode for storage devices citing IEEE 1619-2007.
  6. /// IEEE 1619-2007 provides both a reference implementation and test vectors.
  7. /// The IEEE reference implementation fails to arrive at the expected result
  8. /// for some test vectors.
  9. /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of
  10. /// Operation</A> on the Crypto++ wiki, <A
  11. /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some
  12. /// Blockcipher Modes of Operation</A>, <A
  13. /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation
  14. /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on
  15. /// Storage Devices</A>, <A
  16. /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A>
  17. /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS,
  18. /// inconsistent reference implementation and test vectors</A>.
  19. /// \since Crypto++ 8.3
  20. #ifndef CRYPTOPP_XTS_MODE_H
  21. #define CRYPTOPP_XTS_MODE_H
  22. #include "cryptlib.h"
  23. #include "secblock.h"
  24. #include "modes.h"
  25. #include "misc.h"
  26. /// \brief Enable XTS for wide block ciphers
  27. /// \details XTS is only defined for AES. The library can support wide
  28. /// block ciphers like Kaylna and Threefish since we know the polynomials.
  29. /// To enable wide block ciphers define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt>
  30. /// to non-zero. Note this is a library compile time define.
  31. /// \details There is risk involved with using XTS with wider block ciphers.
  32. /// According to Phillip Rogaway, "The narrow width of the underlying PRP and
  33. /// the poor treatment of fractional final blocks are problems."
  34. /// \sa <A HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf">Evaluation
  35. /// of Some Blockcipher Modes of Operation</A>
  36. /// \since Crypto++ 8.3
  37. #ifndef CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS
  38. # define CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS 0
  39. #endif // CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS
  40. NAMESPACE_BEGIN(CryptoPP)
  41. /// \brief XTS block cipher mode of operation default implementation
  42. /// \since Crypto++ 8.3
  43. class CRYPTOPP_NO_VTABLE XTS_ModeBase : public BlockOrientedCipherModeBase
  44. {
  45. public:
  46. /// \brief The algorithm name
  47. /// \return the algorithm name
  48. /// \details StaticAlgorithmName returns the algorithm's name as a static
  49. /// member function.
  50. CRYPTOPP_STATIC_CONSTEXPR const char* StaticAlgorithmName()
  51. {return "XTS";}
  52. virtual ~XTS_ModeBase() {}
  53. std::string AlgorithmName() const
  54. {return GetBlockCipher().AlgorithmName() + "/XTS";}
  55. std::string AlgorithmProvider() const
  56. {return GetBlockCipher().AlgorithmProvider();}
  57. size_t MinKeyLength() const
  58. {return GetBlockCipher().MinKeyLength()*2;}
  59. size_t MaxKeyLength() const
  60. {return GetBlockCipher().MaxKeyLength()*2;}
  61. size_t DefaultKeyLength() const
  62. {return GetBlockCipher().DefaultKeyLength()*2;}
  63. size_t GetValidKeyLength(size_t n) const
  64. {return 2*GetBlockCipher().GetValidKeyLength((n+1)/2);}
  65. bool IsValidKeyLength(size_t keylength) const
  66. {return keylength == GetValidKeyLength(keylength);}
  67. /// \brief Validates the key length
  68. /// \param length the size of the keying material, in bytes
  69. /// \throw InvalidKeyLength if the key length is invalid
  70. void ThrowIfInvalidKeyLength(size_t length);
  71. /// Provides the block size of the cipher
  72. /// \return the block size of the cipher, in bytes
  73. unsigned int BlockSize() const
  74. {return GetBlockCipher().BlockSize();}
  75. /// \brief Provides the input block size most efficient for this cipher
  76. /// \return The input block size that is most efficient for the cipher
  77. /// \details The base class implementation returns MandatoryBlockSize().
  78. /// \note Optimal input length is
  79. /// <tt>n * OptimalBlockSize() - GetOptimalBlockSizeUsed()</tt> for
  80. /// any <tt>n \> 0</tt>.
  81. unsigned int GetOptimalBlockSize() const
  82. {return GetBlockCipher().BlockSize()*ParallelBlocks;}
  83. unsigned int MinLastBlockSize() const
  84. {return GetBlockCipher().BlockSize()+1;}
  85. unsigned int OptimalDataAlignment() const
  86. {return GetBlockCipher().OptimalDataAlignment();}
  87. /// \brief Validates the block size
  88. /// \param length the block size of the cipher, in bytes
  89. /// \throw InvalidArgument if the block size is invalid
  90. /// \details If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is 0,
  91. /// then CIPHER must be a 16-byte block cipher. If
  92. /// <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is non-zero then
  93. /// CIPHER can be 16, 32, 64, or 128-byte block cipher.
  94. void ThrowIfInvalidBlockSize(size_t length);
  95. void SetKey(const byte *key, size_t length, const NameValuePairs &params = g_nullNameValuePairs);
  96. IV_Requirement IVRequirement() const {return UNIQUE_IV;}
  97. void Resynchronize(const byte *iv, int ivLength=-1);
  98. void ProcessData(byte *outString, const byte *inString, size_t length);
  99. size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength);
  100. /// \brief Resynchronize the cipher
  101. /// \param sector a 64-bit sector number
  102. /// \param order the endian order the word should be written
  103. /// \details The Resynchronize() overload was provided for API
  104. /// compatibility with the IEEE P1619 paper.
  105. void Resynchronize(word64 sector, ByteOrder order=BIG_ENDIAN_ORDER);
  106. protected:
  107. virtual void ResizeBuffers();
  108. inline size_t ProcessLastPlainBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength);
  109. inline size_t ProcessLastCipherBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength);
  110. virtual BlockCipher& AccessBlockCipher() = 0;
  111. virtual BlockCipher& AccessTweakCipher() = 0;
  112. const BlockCipher& GetBlockCipher() const
  113. {return const_cast<XTS_ModeBase*>(this)->AccessBlockCipher();}
  114. const BlockCipher& GetTweakCipher() const
  115. {return const_cast<XTS_ModeBase*>(this)->AccessTweakCipher();}
  116. // Buffers are sized based on ParallelBlocks
  117. AlignedSecByteBlock m_xregister;
  118. AlignedSecByteBlock m_xworkspace;
  119. // Intel lacks the SSE registers to run 8 or 12 parallel blocks.
  120. // Do not change this value after compiling. It has no effect.
  121. #if CRYPTOPP_BOOL_X64 || CRYPTOPP_BOOL_X32 || CRYPTOPP_BOOL_X86
  122. enum {ParallelBlocks = 4};
  123. #else
  124. enum {ParallelBlocks = 12};
  125. #endif
  126. };
  127. /// \brief XTS block cipher mode of operation implementation
  128. /// \tparam CIPHER BlockCipher derived class or type
  129. /// \details XTS_Final() provides access to CIPHER in base class XTS_ModeBase()
  130. /// through an interface. AccessBlockCipher() and AccessTweakCipher() allow
  131. /// the XTS_ModeBase() base class to access the user's block cipher without
  132. /// recompiling the library.
  133. /// \details If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is 0, then CIPHER must
  134. /// be a 16-byte block cipher. If <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> is
  135. /// non-zero then CIPHER can be 16, 32, 64, or 128-byte block cipher.
  136. /// There is risk involved with using XTS with wider block ciphers.
  137. /// According to Phillip Rogaway, "The narrow width of the underlying PRP and
  138. /// the poor treatment of fractional final blocks are problems." To enable
  139. /// wide block cipher support define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> to
  140. /// non-zero.
  141. /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of
  142. /// Operation</A> on the Crypto++ wiki, <A
  143. /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some
  144. /// Blockcipher Modes of Operation</A>, <A
  145. /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation
  146. /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on
  147. /// Storage Devices</A>, <A
  148. /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A>
  149. /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS,
  150. /// inconsistent reference implementation and test vectors</A>.
  151. /// \since Crypto++ 8.3
  152. template <class CIPHER>
  153. class CRYPTOPP_NO_VTABLE XTS_Final : public XTS_ModeBase
  154. {
  155. protected:
  156. BlockCipher& AccessBlockCipher()
  157. {return *m_cipher;}
  158. BlockCipher& AccessTweakCipher()
  159. {return m_tweaker;}
  160. protected:
  161. typename CIPHER::Encryption m_tweaker;
  162. };
  163. /// \brief XTS block cipher mode of operation
  164. /// \tparam CIPHER BlockCipher derived class or type
  165. /// \details XTS mode is a wide block mode defined by IEEE P1619-2008. NIST
  166. /// SP-800-38E approves the mode for storage devices citing IEEE 1619-2007.
  167. /// IEEE 1619-2007 provides both a reference implementation and test vectors.
  168. /// The IEEE reference implementation fails to arrive at the expected result
  169. /// for some test vectors.
  170. /// \details XTS is only defined for AES. The library can support wide
  171. /// block ciphers like Kaylna and Threefish since we know the polynomials.
  172. /// There is risk involved with using XTS with wider block ciphers.
  173. /// According to Phillip Rogaway, "The narrow width of the underlying PRP and
  174. /// the poor treatment of fractional final blocks are problems." To enable
  175. /// wide block cipher support define <tt>CRYPTOPP_XTS_WIDE_BLOCK_CIPHERS</tt> to
  176. /// non-zero.
  177. /// \sa <A HREF="http://www.cryptopp.com/wiki/Modes_of_Operation">Modes of
  178. /// Operation</A> on the Crypto++ wiki, <A
  179. /// HREF="https://web.cs.ucdavis.edu/~rogaway/papers/modes.pdf"> Evaluation of Some
  180. /// Blockcipher Modes of Operation</A>, <A
  181. /// HREF="https://csrc.nist.gov/publications/detail/sp/800-38e/final">Recommendation
  182. /// for Block Cipher Modes of Operation: The XTS-AES Mode for Confidentiality on
  183. /// Storage Devices</A>, <A
  184. /// HREF="http://libeccio.di.unisa.it/Crypto14/Lab/p1619.pdf">IEEE P1619-2007</A>
  185. /// and <A HREF="https://crypto.stackexchange.com/q/74925/10496">IEEE P1619/XTS,
  186. /// inconsistent reference implementation and test vectors</A>.
  187. /// \since Crypto++ 8.3
  188. template <class CIPHER>
  189. struct XTS : public CipherModeDocumentation
  190. {
  191. typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, XTS_Final<CIPHER> > Encryption;
  192. typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Decryption, XTS_Final<CIPHER> > Decryption;
  193. };
  194. // C++03 lacks the mechanics to typedef a template
  195. #define XTS_Mode XTS
  196. NAMESPACE_END
  197. #endif // CRYPTOPP_XTS_MODE_H