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