Coverage Report

Created: 2024-11-21 07:03

/src/cryptopp/xts.h
Line
Count
Source (jump to first uncovered line)
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
2
        {return "XTS";}
58
59
8
    virtual ~XTS_ModeBase() {}
60
61
    std::string AlgorithmName() const
62
0
        {return GetBlockCipher().AlgorithmName() + "/XTS";}
63
    std::string AlgorithmProvider() const
64
0
        {return GetBlockCipher().AlgorithmProvider();}
65
66
    size_t MinKeyLength() const
67
0
        {return GetBlockCipher().MinKeyLength()*2;}
68
    size_t MaxKeyLength() const
69
0
        {return GetBlockCipher().MaxKeyLength()*2;}
70
    size_t DefaultKeyLength() const
71
0
        {return GetBlockCipher().DefaultKeyLength()*2;}
72
    size_t GetValidKeyLength(size_t n) const
73
0
        {return 2*GetBlockCipher().GetValidKeyLength((n+1)/2);}
74
    bool IsValidKeyLength(size_t keylength) const
75
0
        {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
0
        {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
0
        {return GetBlockCipher().BlockSize()*ParallelBlocks;}
95
    unsigned int MinLastBlockSize() const
96
0
        {return GetBlockCipher().BlockSize()+1;}
97
    unsigned int OptimalDataAlignment() const
98
0
        {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
0
    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
14
        {return const_cast<XTS_ModeBase*>(this)->AccessBlockCipher();}
133
    const BlockCipher& GetTweakCipher() const
134
0
        {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
14
        {return *m_cipher;}
180
    BlockCipher& AccessTweakCipher()
181
0
        {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