Crypto++ 8.7
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
45NAMESPACE_BEGIN(CryptoPP)
46
47/// \brief XTS block cipher mode of operation default implementation
48/// \since Crypto++ 8.3
49class CRYPTOPP_NO_VTABLE XTS_ModeBase : public BlockOrientedCipherModeBase
50{
51public:
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
122protected:
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
174template <class CIPHER>
175class CRYPTOPP_NO_VTABLE XTS_Final : public XTS_ModeBase
176{
177protected:
178 BlockCipher& AccessBlockCipher()
179 {return *m_cipher;}
180 BlockCipher& AccessTweakCipher()
181 {return m_tweaker;}
182
183protected:
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
212template <class CIPHER>
214{
217};
218
219// C++03 lacks the mechanics to typedef a template
220#define XTS_Mode XTS
221
222NAMESPACE_END
223
224#endif // CRYPTOPP_XTS_MODE_H
SecBlock using AllocatorWithCleanup<byte, true> typedef.
Definition: secblock.h:1230
Interface for one direction (encryption or decryption) of a block cipher.
Definition: cryptlib.h:1283
Block cipher mode of operation default implementation.
Definition: modes.h:251
Block cipher mode of operation aggregate.
Definition: modes.h:347
Interface for retrieving values given their names.
Definition: cryptlib.h:322
IV_Requirement
Secure IVs requirements as enumerated values.
Definition: cryptlib.h:719
Interface for one direction (encryption or decryption) of a stream cipher or cipher mode.
Definition: cryptlib.h:1291
XTS block cipher mode of operation implementation.
Definition: xts.h:176
XTS block cipher mode of operation default implementation.
Definition: xts.h:50
unsigned int MinLastBlockSize() const
Provides the size of the last block.
Definition: xts.h:95
size_t DefaultKeyLength() const
Returns default key length.
Definition: xts.h:70
bool IsValidKeyLength(size_t keylength) const
Returns whether keylength is a valid key length.
Definition: xts.h:74
std::string AlgorithmProvider() const
Retrieve the provider of this algorithm.
Definition: xts.h:63
IV_Requirement IVRequirement() const
Minimal requirement for secure IVs.
Definition: xts.h:110
size_t GetValidKeyLength(size_t n) const
Returns a valid key length for the algorithm.
Definition: xts.h:72
size_t MaxKeyLength() const
Returns largest valid key length.
Definition: xts.h:68
unsigned int OptimalDataAlignment() const
Provides input and output data alignment for optimal performance.
Definition: xts.h:97
unsigned int BlockSize() const
Provides the block size of the cipher.
Definition: xts.h:84
unsigned int GetOptimalBlockSize() const
Provides the input block size most efficient for this cipher.
Definition: xts.h:93
std::string AlgorithmName() const
Provides the name of this algorithm.
Definition: xts.h:61
size_t MinKeyLength() const
Returns smallest valid key length.
Definition: xts.h:66
unsigned long long word64
64-bit unsigned datatype
Definition: config_int.h:91
Abstract base classes that provide a uniform interface to this library.
const NameValuePairs & g_nullNameValuePairs
An empty set of name-value pairs.
Definition: cryptlib.h:529
ByteOrder
Provides the byte ordering.
Definition: cryptlib.h:143
@ BIG_ENDIAN_ORDER
byte order is big-endian
Definition: cryptlib.h:147
Utility functions for the Crypto++ library.
Classes for block cipher modes of operation.
Crypto++ library namespace.
Classes and functions for secure memory allocations.
Block cipher mode of operation information.
Definition: modes.h:45
XTS block cipher mode of operation.
Definition: xts.h:214