summaryrefslogtreecommitdiff
path: root/seckey.h
blob: fe6f04d369f25f9994c2d4dd06dfcd79207b1acf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
// seckey.h - originally written and placed in the public domain by Wei Dai

/// \file seckey.h
/// \brief Classes and functions for implementing secret key algorithms.

#ifndef CRYPTOPP_SECKEY_H
#define CRYPTOPP_SECKEY_H

#include "config.h"
#include "cryptlib.h"
#include "misc.h"
#include "simple.h"
#include "stdcpp.h"

#if CRYPTOPP_MSC_VERSION
# pragma warning(push)
# pragma warning(disable: 4189 4296)
#endif

// Issue 340
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic push
# pragma GCC diagnostic ignored "-Wconversion"
# pragma GCC diagnostic ignored "-Wsign-conversion"
#endif

NAMESPACE_BEGIN(CryptoPP)

/// \brief Inverts the cipher's direction
/// \param dir the cipher's direction
/// \returns DECRYPTION if \ref CipherDir "dir" is ENCRYPTION, DECRYPTION otherwise
inline CipherDir ReverseCipherDir(CipherDir dir)
{
	return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION;
}

/// \brief Inherited by algorithms with fixed block size
/// \tparam N the blocksize of the algorithm
template <unsigned int N>
class FixedBlockSize
{
public:
	/// \brief The block size of the algorithm provided as a constant.
	CRYPTOPP_CONSTANT(BLOCKSIZE = N)
;
};

// ************** rounds ***************

/// \brief Inherited by algorithms with fixed number of rounds
/// \tparam R the number of rounds used by the algorithm
template <unsigned int R>
class FixedRounds
{
public:
	/// \brief The number of rounds for the algorithm provided as a constant.
	CRYPTOPP_CONSTANT(ROUNDS = R)
;
};

/// \brief Inherited by algorithms with variable number of rounds
/// \tparam D Default number of rounds
/// \tparam N Minimum number of rounds
/// \tparam M Maximum number of rounds
template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX>		// use INT_MAX here because enums are treated as signed ints
class VariableRounds
{
public:
	/// \brief The default number of rounds for the algorithm provided as a constant.
	CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D)
;
	/// \brief The minimum number of rounds for the algorithm provided as a constant.
	CRYPTOPP_CONSTANT(MIN_ROUNDS = N)
;
	/// \brief The maximum number of rounds for the algorithm provided as a constant.
	CRYPTOPP_CONSTANT(MAX_ROUNDS = M)
;
	/// \brief The default number of rounds for the algorithm based on key length
	///   provided by a static function.
	/// \param keylength the size of the key, in bytes
	/// \details keylength is unused in the default implementation.
	CRYPTOPP_STATIC_CONSTEXPR unsigned int StaticGetDefaultRounds(size_t keylength)
	{
		return CRYPTOPP_UNUSED(keylength), static_cast<unsigned int>(DEFAULT_ROUNDS);
	}

protected:
	/// \brief Validates the number of rounds for an algorithm.
	/// \param rounds the candidate number of rounds
	/// \param alg an Algorithm object used if the number of rounds are invalid
	/// \throws InvalidRounds if the number of rounds are invalid
	/// \details ThrowIfInvalidRounds() validates the number of rounds and throws if invalid.
	inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg)
	{
		if (M == INT_MAX) // Coverity and result_independent_of_operands
		{
			if (rounds < MIN_ROUNDS)
				throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds);
		}
		else
		{
			if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS)
				throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds);
		}
	}

	/// \brief Validates the number of rounds for an algorithm
	/// \param param the candidate number of rounds
	/// \param alg an Algorithm object used if the number of rounds are invalid
	/// \returns the number of rounds for the algorithm
	/// \throws InvalidRounds if the number of rounds are invalid
	/// \details GetRoundsAndThrowIfInvalid() validates the number of rounds and throws if invalid.
	inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs &param, const Algorithm *alg)
	{
		int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS);
		ThrowIfInvalidRounds(rounds, alg);
		return static_cast<unsigned int>(rounds);
	}
};

// ************** key length ***************

/// \brief Inherited by keyed algorithms with fixed key length
/// \tparam N Default key length, in bytes
/// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
/// \tparam IV_L default IV length, in bytes
/// \sa SimpleKeyingInterface
template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
class FixedKeyLength
{
public:
	/// \brief The default key length used by the algorithm provided as a constant
	/// \details KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(KEYLENGTH=N)
;
	/// \brief The minimum key length used by the algorithm provided as a constant
	/// \details MIN_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N)
;
	/// \brief The maximum key length used by the algorithm provided as a constant
	/// \details MAX_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N)
;
	/// \brief The default key length used by the algorithm provided as a constant
	/// \details DEFAULT_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N)
;
	/// \brief The default IV requirements for the algorithm provided as a constant
	/// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
	///  in cryptlib.h for allowed values.
	CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ)
;
	/// \brief The default IV length used by the algorithm provided as a constant
	/// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
	CRYPTOPP_CONSTANT(IV_LENGTH = IV_L)
;
	/// \brief The default key length for the algorithm provided by a static function.
	/// \param keylength the size of the key, in bytes
	/// \details The default implementation returns KEYLENGTH. keylength is unused
	///   in the default implementation.
	CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
	{
		return CRYPTOPP_UNUSED(keylength), static_cast<size_t>(KEYLENGTH);
	}
};

/// \brief Inherited by keyed algorithms with variable key length
/// \tparam D Default key length, in bytes
/// \tparam N Minimum key length, in bytes
/// \tparam M Maximum key length, in bytes
/// \tparam Q Default key length multiple, in bytes. The default multiple is 1.
/// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
/// \tparam IV_L default IV length, in bytes. The default length is 0.
/// \sa SimpleKeyingInterface
template <unsigned int D, unsigned int N, unsigned int M, unsigned int Q = 1, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
class VariableKeyLength
{
	// Make these private to avoid Doxygen documenting them in all derived classes
	CRYPTOPP_COMPILE_ASSERT(Q > 0);
	CRYPTOPP_COMPILE_ASSERT(N % Q == 0);
	CRYPTOPP_COMPILE_ASSERT(M % Q == 0);
	CRYPTOPP_COMPILE_ASSERT(N < M);
	CRYPTOPP_COMPILE_ASSERT(D >= N);
	CRYPTOPP_COMPILE_ASSERT(M >= D);

public:
	/// \brief The minimum key length used by the algorithm provided as a constant
	/// \details MIN_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N)
;
	/// \brief The maximum key length used by the algorithm provided as a constant
	/// \details MAX_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M)
;
	/// \brief The default key length used by the algorithm provided as a constant
	/// \details DEFAULT_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D)
;
	/// \brief The key length multiple used by the algorithm provided as a constant
	/// \details MAX_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q)
;
	/// \brief The default IV requirements for the algorithm provided as a constant
	/// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
	///  in cryptlib.h for allowed values.
	CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ)
;
	/// \brief The default initialization vector length for the algorithm provided as a constant
	/// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
	CRYPTOPP_CONSTANT(IV_LENGTH=IV_L)
;
	/// \brief Provides a valid key length for the algorithm provided by a static function.
	/// \param keylength the size of the key, in bytes
	/// \details If keylength is less than MIN_KEYLENGTH, then the function returns
	///   MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function
	///   returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE,
	///   then keylength is returned. Otherwise, the function returns keylength rounded
	///   \a down to the next smaller multiple of KEYLENGTH_MULTIPLE.
	/// \details keylength is provided in bytes, not bits.
	CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
	{
		return (keylength <= N) ? N :
			(keylength >= M) ? M :
			(keylength+Q-1) - (keylength+Q-1)%Q;
	}
};

/// \brief Provides key lengths based on another class's key length
/// \tparam T another FixedKeyLength or VariableKeyLength class
/// \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
/// \tparam IV_L default IV length, in bytes
/// \sa SimpleKeyingInterface
template <class T, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
class SameKeyLengthAs
{
public:
	/// \brief The minimum key length used by the algorithm provided as a constant
	/// \details MIN_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH)
;
	/// \brief The maximum key length used by the algorithm provided as a constant
	/// \details MIN_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH)
;
	/// \brief The default key length used by the algorithm provided as a constant
	/// \details MIN_KEYLENGTH is provided in bytes, not bits
	CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH)
;
	/// \brief The default IV requirements for the algorithm provided as a constant
	/// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
	///  in cryptlib.h for allowed values.
	CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ)
;
	/// \brief The default initialization vector length for the algorithm provided as a constant
	/// \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
	CRYPTOPP_CONSTANT(IV_LENGTH=IV_L)
;
	/// \brief Provides a valid key length for the algorithm provided by a static function.
	/// \param keylength the size of the key, in bytes
	/// \details If keylength is less than MIN_KEYLENGTH, then the function returns
	///   MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function
	///   returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE,
	///   then keylength is returned. Otherwise, the function returns keylength rounded
	///   \a down to the next smaller multiple of KEYLENGTH_MULTIPLE.
	/// \details keylength is provided in bytes, not bits.
	CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
		{return T::StaticGetValidKeyLength(keylength);}
};

// ************** implementation helper for SimpleKeyingInterface ***************

/// \brief Provides a base implementation of SimpleKeyingInterface
/// \tparam BASE a SimpleKeyingInterface derived class
/// \tparam INFO a SimpleKeyingInterface derived class
/// \details SimpleKeyingInterfaceImpl() provides a default implementation for ciphers providing a keying interface.
///   Functions are virtual and not eligible for C++11 <tt>constexpr</tt>-ness.
/// \sa Algorithm(), SimpleKeyingInterface()
template <class BASE, class INFO = BASE>
class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE
{
public:
	/// \brief The minimum key length used by the algorithm
	/// \returns minimum key length used by the algorithm, in bytes
	size_t MinKeyLength() const
		{return INFO::MIN_KEYLENGTH;}

	/// \brief The maximum key length used by the algorithm
	/// \returns maximum key length used by the algorithm, in bytes
	size_t MaxKeyLength() const
		{return static_cast<size_t>(INFO::MAX_KEYLENGTH);}

	/// \brief The default key length used by the algorithm
	/// \returns default key length used by the algorithm, in bytes
	size_t DefaultKeyLength() const
		{return INFO::DEFAULT_KEYLENGTH;}

	/// \brief Provides a valid key length for the algorithm
	/// \param keylength the size of the key, in bytes
	/// \returns the valid key length, in bytes
	/// \details keylength is provided in bytes, not bits. If keylength is less than MIN_KEYLENGTH,
	///   then the function returns MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH,
	///   then the function returns MAX_KEYLENGTH. if If keylength is a multiple of KEYLENGTH_MULTIPLE,
	///   then keylength is returned. Otherwise, the function returns a \a lower multiple of
	///   KEYLENGTH_MULTIPLE.
	size_t GetValidKeyLength(size_t keylength) const {return INFO::StaticGetValidKeyLength(keylength);}

	/// \brief The default IV requirements for the algorithm
	/// \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
	///  in cryptlib.h for allowed values.
	SimpleKeyingInterface::IV_Requirement IVRequirement() const
		{return static_cast<SimpleKeyingInterface::IV_Requirement>(INFO::IV_REQUIREMENT);}

	/// \brief The initialization vector length for the algorithm
	/// \details IVSize is provided in bytes, not bits. The default implementation uses
	///   IV_LENGTH, which is 0.
	unsigned int IVSize() const
		{return INFO::IV_LENGTH;}
};

/// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for block ciphers
/// \tparam INFO a SimpleKeyingInterface derived class
/// \tparam BASE a SimpleKeyingInterface derived class
/// \details BlockCipherImpl() provides a default implementation for block ciphers using AlgorithmImpl()
///   and SimpleKeyingInterfaceImpl(). Functions are virtual and not eligible for C++11 <tt>constexpr</tt>-ness.
/// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl()
template <class INFO, class BASE = BlockCipher>
class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
{
public:
	/// Provides the block size of the algorithm
	/// \returns the block size of the algorithm, in bytes
	unsigned int BlockSize() const {return this->BLOCKSIZE;}
};

/// \brief Provides class member functions to key a block cipher
/// \tparam DIR a CipherDir
/// \tparam BASE a BlockCipherImpl derived class
template <CipherDir DIR, class BASE>
class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE>
{
public:
	/// \brief Construct a default BlockCipherFinal
	/// \details The cipher is not keyed.
 	BlockCipherFinal() {}

	/// \brief Construct a BlockCipherFinal
	/// \param key a byte array used to key the cipher
	/// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
	///    SimpleKeyingInterface::SetKey.
	BlockCipherFinal(const byte *key)
		{this->SetKey(key, this->DEFAULT_KEYLENGTH);}

	/// \brief Construct a BlockCipherFinal
	/// \param key a byte array used to key the cipher
	/// \param length the length of the byte array
	/// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
	///    SimpleKeyingInterface::SetKey.
	BlockCipherFinal(const byte *key, size_t length)
		{this->SetKey(key, length);}

	/// \brief Construct a BlockCipherFinal
	/// \param key a byte array used to key the cipher
	/// \param length the length of the byte array
	/// \param rounds the number of rounds
	/// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
	///    SimpleKeyingInterface::SetKeyWithRounds.
	BlockCipherFinal(const byte *key, size_t length, unsigned int rounds)
		{this->SetKeyWithRounds(key, length, rounds);}

	/// \brief Provides the direction of the cipher
	/// \returns true if DIR is ENCRYPTION, false otherwise
	/// \sa GetCipherDirection(), IsPermutation()
	bool IsForwardTransformation() const {return DIR == ENCRYPTION;}
};

/// \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for message authentication codes
/// \tparam INFO a SimpleKeyingInterface derived class
/// \tparam BASE a SimpleKeyingInterface derived class
/// \details MessageAuthenticationCodeImpl() provides a default implementation for message authentication codes
///   using AlgorithmImpl() and SimpleKeyingInterfaceImpl(). Functions are virtual and not subject to C++11
///   <tt>constexpr</tt>.
/// \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl()
template <class BASE, class INFO = BASE>
class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
{
};

/// \brief Provides class member functions to key a message authentication code
/// \tparam BASE a BlockCipherImpl derived class
/// \details A default implementation for MessageAuthenticationCode
template <class BASE>
class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> >
{
public:
	/// \brief Construct a default MessageAuthenticationCodeFinal
	/// \details The message authentication code is not keyed.
 	MessageAuthenticationCodeFinal() {}
	/// \brief Construct a BlockCipherFinal
	/// \param key a byte array used to key the algorithm
	/// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
	///    SimpleKeyingInterface::SetKey.
	MessageAuthenticationCodeFinal(const byte *key)
		{this->SetKey(key, this->DEFAULT_KEYLENGTH);}
	/// \brief Construct a BlockCipherFinal
	/// \param key a byte array used to key the algorithm
	/// \param length the length of the byte array
	/// \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
	///    SimpleKeyingInterface::SetKey.
	MessageAuthenticationCodeFinal(const byte *key, size_t length)
		{this->SetKey(key, length);}
};

// ************** documentation ***************

/// \brief Provides Encryption and Decryption typedefs used by derived classes to
///    implement a block cipher
/// \details These objects usually should not be used directly. See CipherModeDocumentation
///    instead. Each class derived from this one defines two types, Encryption and Decryption,
///    both of which implement the BlockCipher interface.
struct BlockCipherDocumentation
{
	/// implements the BlockCipher interface
	typedef BlockCipher Encryption;
	/// implements the BlockCipher interface
	typedef BlockCipher Decryption;
};

/// \brief Provides Encryption and Decryption typedefs used by derived classes to
///    implement a symmetric cipher
/// \details Each class derived from this one defines two types, Encryption and Decryption,
///    both of which implement the SymmetricCipher interface. Two types of classes derive
///    from this class: stream ciphers and block cipher modes. Stream ciphers can be used
///    alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation
///    for more for information about using cipher modes and block ciphers.
struct SymmetricCipherDocumentation
{
	/// implements the SymmetricCipher interface
	typedef SymmetricCipher Encryption;
	/// implements the SymmetricCipher interface
	typedef SymmetricCipher Decryption;
};

/// \brief Provides Encryption and Decryption typedefs used by derived classes to
///    implement an authenticated encryption cipher
/// \details Each class derived from this one defines two types, Encryption and Decryption,
///    both of which implement the AuthenticatedSymmetricCipher interface.
struct AuthenticatedSymmetricCipherDocumentation
{
	/// implements the AuthenticatedSymmetricCipher interface
	typedef AuthenticatedSymmetricCipher Encryption;
	/// implements the AuthenticatedSymmetricCipher interface
	typedef AuthenticatedSymmetricCipher Decryption;
};

NAMESPACE_END

#if CRYPTOPP_MSC_VERSION
# pragma warning(pop)
#endif

// Issue 340
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic pop
#endif

#endif