Crypto++ 8.5 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 /// \return 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 /// \throw 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 /// \throw 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>
213 struct XTS : public CipherModeDocumentation
214 {
215 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Encryption, XTS_Final<CIPHER> > Encryption;
216 typedef CipherModeFinalTemplate_CipherHolder<typename CIPHER::Decryption, XTS_Final<CIPHER> > Decryption;
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:1290
XTS_Final
XTS block cipher mode of operation implementation.
Definition: xts.h:175
word64
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
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:1282
BlockOrientedCipherModeBase
Block cipher mode of operation default implementation.
Definition: modes.h:250
AlignedSecByteBlock
SecBlock using AllocatorWithCleanup<byte, true> typedef.
Definition: secblock.h:1119
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