monotone

monotone Mtn Source Tree

Root/cryptopp/modes.h

1#ifndef CRYPTOPP_MODES_H
2#define CRYPTOPP_MODES_H
3
4/*! \file
5*/
6
7#include "cryptlib.h"
8#include "secblock.h"
9#include "misc.h"
10#include "strciphr.h"
11#include "argnames.h"
12#include "algparam.h"
13
14NAMESPACE_BEGIN(CryptoPP)
15
16//! Cipher mode documentation. See NIST SP 800-38A for definitions of these modes.
17
18/*! Each class derived from this one defines two types, Encryption and Decryption,
19both of which implement the SymmetricCipher interface.
20For each mode there are two classes, one of which is a template class,
21and the other one has a name that ends in "_ExternalCipher".
22The "external cipher" mode objects hold a reference to the underlying block cipher,
23instead of holding an instance of it. The reference must be passed in to the constructor.
24For the "cipher holder" classes, the CIPHER template parameter should be a class
25derived from BlockCipherDocumentation, for example DES or AES.
26*/
27struct CipherModeDocumentation : public SymmetricCipherDocumentation
28{
29};
30
31class CipherModeBase : public SymmetricCipher
32{
33public:
34unsigned int MinKeyLength() const {return m_cipher->MinKeyLength();}
35unsigned int MaxKeyLength() const {return m_cipher->MaxKeyLength();}
36unsigned int DefaultKeyLength() const {return m_cipher->DefaultKeyLength();}
37unsigned int GetValidKeyLength(unsigned int n) const {return m_cipher->GetValidKeyLength(n);}
38bool IsValidKeyLength(unsigned int n) const {return m_cipher->IsValidKeyLength(n);}
39
40void SetKey(const byte *key, unsigned int length, const NameValuePairs &params = g_nullNameValuePairs);
41
42unsigned int OptimalDataAlignment() const {return BlockSize();}
43
44unsigned int IVSize() const {return BlockSize();}
45void GetNextIV(byte *IV);
46virtual IV_Requirement IVRequirement() const =0;
47
48protected:
49inline unsigned int BlockSize() const {assert(m_register.size() > 0); return m_register.size();}
50void SetIV(const byte *iv);
51virtual void SetFeedbackSize(unsigned int feedbackSize)
52{
53if (!(feedbackSize == 0 || feedbackSize == BlockSize()))
54throw InvalidArgument("CipherModeBase: feedback size cannot be specified for this cipher mode");
55}
56virtual void ResizeBuffers()
57{
58m_register.New(m_cipher->BlockSize());
59}
60virtual void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length) =0;
61
62BlockCipher *m_cipher;
63SecByteBlock m_register;
64};
65
66template <class POLICY_INTERFACE>
67class ModePolicyCommonTemplate : public CipherModeBase, public POLICY_INTERFACE
68{
69unsigned int GetAlignment() const {return m_cipher->BlockAlignment();}
70void CipherSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
71{
72m_cipher->SetKey(key, length, params);
73ResizeBuffers();
74int feedbackSize = params.GetIntValueWithDefault(Name::FeedbackSize(), 0);
75SetFeedbackSize(feedbackSize);
76const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL);
77SetIV(iv);
78}
79};
80
81class CFB_ModePolicy : public ModePolicyCommonTemplate<CFB_CipherAbstractPolicy>
82{
83public:
84IV_Requirement IVRequirement() const {return RANDOM_IV;}
85
86protected:
87unsigned int GetBytesPerIteration() const {return m_feedbackSize;}
88byte * GetRegisterBegin() {return m_register + BlockSize() - m_feedbackSize;}
89void TransformRegister()
90{
91m_cipher->ProcessBlock(m_register, m_temp);
92memmove(m_register, m_register+m_feedbackSize, BlockSize()-m_feedbackSize);
93memcpy(m_register+BlockSize()-m_feedbackSize, m_temp, m_feedbackSize);
94}
95void CipherResynchronize(const byte *iv)
96{
97memcpy(m_register, iv, BlockSize());
98TransformRegister();
99}
100void SetFeedbackSize(unsigned int feedbackSize)
101{
102if (feedbackSize > BlockSize())
103throw InvalidArgument("CFB_Mode: invalid feedback size");
104m_feedbackSize = feedbackSize ? feedbackSize : BlockSize();
105}
106void ResizeBuffers()
107{
108CipherModeBase::ResizeBuffers();
109m_temp.New(BlockSize());
110}
111
112SecByteBlock m_temp;
113unsigned int m_feedbackSize;
114};
115
116class OFB_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
117{
118unsigned int GetBytesPerIteration() const {return BlockSize();}
119unsigned int GetIterationsToBuffer() const {return 1;}
120void WriteKeystream(byte *keystreamBuffer, unsigned int iterationCount)
121{
122assert(iterationCount == 1);
123m_cipher->ProcessBlock(keystreamBuffer);
124}
125void CipherResynchronize(byte *keystreamBuffer, const byte *iv)
126{
127memcpy(keystreamBuffer, iv, BlockSize());
128}
129bool IsRandomAccess() const {return false;}
130IV_Requirement IVRequirement() const {return STRUCTURED_IV;}
131};
132
133class CTR_ModePolicy : public ModePolicyCommonTemplate<AdditiveCipherAbstractPolicy>
134{
135unsigned int GetBytesPerIteration() const {return BlockSize();}
136unsigned int GetIterationsToBuffer() const {return m_cipher->OptimalNumberOfParallelBlocks();}
137void WriteKeystream(byte *buffer, unsigned int iterationCount)
138{OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
139bool CanOperateKeystream() const {return true;}
140void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount);
141void CipherResynchronize(byte *keystreamBuffer, const byte *iv);
142bool IsRandomAccess() const {return true;}
143void SeekToIteration(dword iterationCount);
144IV_Requirement IVRequirement() const {return STRUCTURED_IV;}
145
146inline void ProcessMultipleBlocks(byte *output, const byte *input, unsigned int n);
147
148SecByteBlock m_counterArray;
149};
150
151class BlockOrientedCipherModeBase : public CipherModeBase
152{
153public:
154void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length);
155unsigned int MandatoryBlockSize() const {return BlockSize();}
156bool IsRandomAccess() const {return false;}
157bool IsSelfInverting() const {return false;}
158bool IsForwardTransformation() const {return m_cipher->IsForwardTransformation();}
159void Resynchronize(const byte *iv) {memcpy(m_register, iv, BlockSize());}
160void ProcessData(byte *outString, const byte *inString, unsigned int length);
161
162protected:
163bool RequireAlignedInput() const {return true;}
164virtual void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks) =0;
165void ResizeBuffers()
166{
167CipherModeBase::ResizeBuffers();
168m_buffer.New(BlockSize());
169}
170
171SecByteBlock m_buffer;
172};
173
174class ECB_OneWay : public BlockOrientedCipherModeBase
175{
176public:
177IV_Requirement IVRequirement() const {return NOT_RESYNCHRONIZABLE;}
178unsigned int OptimalBlockSize() const {return BlockSize() * m_cipher->OptimalNumberOfParallelBlocks();}
179void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks)
180{m_cipher->ProcessAndXorMultipleBlocks(inString, NULL, outString, numberOfBlocks);}
181};
182
183class CBC_ModeBase : public BlockOrientedCipherModeBase
184{
185public:
186IV_Requirement IVRequirement() const {return UNPREDICTABLE_RANDOM_IV;}
187bool RequireAlignedInput() const {return false;}
188unsigned int MinLastBlockSize() const {return 0;}
189};
190
191class CBC_Encryption : public CBC_ModeBase
192{
193public:
194void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
195};
196
197class CBC_CTS_Encryption : public CBC_Encryption
198{
199public:
200void SetStolenIV(byte *iv) {m_stolenIV = iv;}
201unsigned int MinLastBlockSize() const {return BlockSize()+1;}
202void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length);
203
204protected:
205void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
206{
207CBC_Encryption::UncheckedSetKey(params, key, length);
208m_stolenIV = params.GetValueWithDefault(Name::StolenIV(), (byte *)NULL);
209}
210
211byte *m_stolenIV;
212};
213
214class CBC_Decryption : public CBC_ModeBase
215{
216public:
217void ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks);
218
219protected:
220void ResizeBuffers()
221{
222BlockOrientedCipherModeBase::ResizeBuffers();
223m_temp.New(BlockSize());
224}
225SecByteBlock m_temp;
226};
227
228class CBC_CTS_Decryption : public CBC_Decryption
229{
230public:
231unsigned int MinLastBlockSize() const {return BlockSize()+1;}
232void ProcessLastBlock(byte *outString, const byte *inString, unsigned int length);
233};
234
235//! .
236template <class CIPHER, class BASE>
237class CipherModeFinalTemplate_CipherHolder : public ObjectHolder<CIPHER>, public BASE
238{
239public:
240CipherModeFinalTemplate_CipherHolder()
241{
242m_cipher = &m_object;
243ResizeBuffers();
244}
245CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length)
246{
247m_cipher = &m_object;
248SetKey(key, length);
249}
250CipherModeFinalTemplate_CipherHolder(const byte *key, unsigned int length, const byte *iv, int feedbackSize = 0)
251{
252m_cipher = &m_object;
253SetKey(key, length, MakeParameters("IV", iv)("FeedbackSize", feedbackSize));
254}
255};
256
257//! .
258template <class BASE>
259class CipherModeFinalTemplate_ExternalCipher : public BASE
260{
261public:
262CipherModeFinalTemplate_ExternalCipher(BlockCipher &cipher, const byte *iv = NULL, int feedbackSize = 0)
263{
264m_cipher = &cipher;
265ResizeBuffers();
266SetFeedbackSize(feedbackSize);
267SetIV(iv);
268}
269};
270
271//! CFB mode
272template <class CIPHER>
273struct CFB_Mode : public CipherModeDocumentation
274{
275typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
276typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
277};
278
279//! CFB mode, external cipher
280struct CFB_Mode_ExternalCipher : public CipherModeDocumentation
281{
282typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Encryption;
283typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> > > > Decryption;
284};
285
286//! OFB mode
287template <class CIPHER>
288struct OFB_Mode : public CipherModeDocumentation
289{
290typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
291typedef Encryption Decryption;
292};
293
294//! OFB mode, external cipher
295struct OFB_Mode_ExternalCipher : public CipherModeDocumentation
296{
297typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> > > > Encryption;
298typedef Encryption Decryption;
299};
300
301//! CTR mode
302template <class CIPHER>
303struct CTR_Mode : public CipherModeDocumentation
304{
305typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
306typedef Encryption Decryption;
307};
308
309//! CTR mode, external cipher
310struct CTR_Mode_ExternalCipher : public CipherModeDocumentation
311{
312typedef CipherModeFinalTemplate_ExternalCipher<ConcretePolicyHolder<Empty, AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> > > > Encryption;
313typedef Encryption Decryption;
314};
315
316//! ECB mode
317template <class CIPHER>
318struct ECB_Mode : public CipherModeDocumentation
319{
320typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, ECB_OneWay> Encryption;
321typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, ECB_OneWay> Decryption;
322};
323
324//! ECB mode, external cipher
325struct ECB_Mode_ExternalCipher : public CipherModeDocumentation
326{
327typedef CipherModeFinalTemplate_ExternalCipher<ECB_OneWay> Encryption;
328typedef Encryption Decryption;
329};
330
331//! CBC mode
332template <class CIPHER>
333struct CBC_Mode : public CipherModeDocumentation
334{
335typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_Encryption> Encryption;
336typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_Decryption> Decryption;
337};
338
339//! CBC mode, external cipher
340struct CBC_Mode_ExternalCipher : public CipherModeDocumentation
341{
342typedef CipherModeFinalTemplate_ExternalCipher<CBC_Encryption> Encryption;
343typedef CipherModeFinalTemplate_ExternalCipher<CBC_Decryption> Decryption;
344};
345
346//! CBC mode with ciphertext stealing
347template <class CIPHER>
348struct CBC_CTS_Mode : public CipherModeDocumentation
349{
350typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Encryption, CBC_CTS_Encryption> Encryption;
351typedef CipherModeFinalTemplate_CipherHolder<CPP_TYPENAME CIPHER::Decryption, CBC_CTS_Decryption> Decryption;
352};
353
354//! CBC mode with ciphertext stealing, external cipher
355struct CBC_CTS_Mode_ExternalCipher : public CipherModeDocumentation
356{
357typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Encryption> Encryption;
358typedef CipherModeFinalTemplate_ExternalCipher<CBC_CTS_Decryption> Decryption;
359};
360
361#ifdef CRYPTOPP_MAINTAIN_BACKWARDS_COMPATIBILITY
362typedef CFB_Mode_ExternalCipher::Encryption CFBEncryption;
363typedef CFB_Mode_ExternalCipher::Decryption CFBDecryption;
364typedef OFB_Mode_ExternalCipher::Encryption OFB;
365typedef CTR_Mode_ExternalCipher::Encryption CounterMode;
366#endif
367
368NAMESPACE_END
369
370#endif

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status