monotone

monotone Mtn Source Tree

Root/cryptopp/strciphr.h

1/*! \file
2 This file contains helper classes for implementing stream ciphers.
3
4All this infrastructure may look very complex compared to what's in Crypto++ 4.x,
5but stream ciphers implementations now support a lot of new functionality,
6including better performance (minimizing copying), resetting of keys and IVs, and methods to
7query which features are supported by a cipher.
8
9Here's an explanation of these classes. The word "policy" is used here to mean a class with a
10set of methods that must be implemented by individual stream cipher implementations.
11This is usually much simpler than the full stream cipher API, which is implemented by
12either AdditiveCipherTemplate or CFB_CipherTemplate using the policy. So for example, an
13implementation of SEAL only needs to implement the AdditiveCipherAbstractPolicy interface
14(since it's an additive cipher, i.e., it xors a keystream into the plaintext).
15See this line in seal.h:
16
17typedef SymmetricCipherFinalTemplate<ConcretePolicyHolder<SEAL_Policy<B>, AdditiveCipherTemplate<> > > Encryption;
18
19AdditiveCipherTemplate and CFB_CipherTemplate are designed so that they don't need
20to take a policy class as a template parameter (although this is allowed), so that
21their code is not duplicated for each new cipher. Instead they each
22get a reference to an abstract policy interface by calling AccessPolicy() on itself, so
23AccessPolicy() must be overriden to return the actual policy reference. This is done
24by the ConceretePolicyHolder class. Finally, SymmetricCipherFinalTemplate implements the constructors and
25other functions that must be implemented by the most derived class.
26*/
27
28#ifndef CRYPTOPP_STRCIPHR_H
29#define CRYPTOPP_STRCIPHR_H
30
31#include "seckey.h"
32#include "secblock.h"
33
34NAMESPACE_BEGIN(CryptoPP)
35
36template <class POLICY_INTERFACE, class BASE = Empty>
37class AbstractPolicyHolder : public BASE
38{
39public:
40typedef POLICY_INTERFACE PolicyInterface;
41
42protected:
43virtual const POLICY_INTERFACE & GetPolicy() const =0;
44virtual POLICY_INTERFACE & AccessPolicy() =0;
45};
46
47template <class POLICY, class BASE, class POLICY_INTERFACE = CPP_TYPENAME BASE::PolicyInterface>
48class ConcretePolicyHolder : public BASE, protected POLICY
49{
50protected:
51const POLICY_INTERFACE & GetPolicy() const {return *this;}
52POLICY_INTERFACE & AccessPolicy() {return *this;}
53};
54
55enum KeystreamOperation {WRITE_KEYSTREAM, XOR_KEYSTREAM, XOR_KEYSTREAM_INPLACE};
56
57struct AdditiveCipherAbstractPolicy
58{
59virtual unsigned int GetAlignment() const =0;
60virtual unsigned int GetBytesPerIteration() const =0;
61virtual unsigned int GetIterationsToBuffer() const =0;
62virtual void WriteKeystream(byte *keystreamBuffer, unsigned int iterationCount) =0;
63virtual bool CanOperateKeystream() const {return false;}
64virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount) {assert(false);}
65virtual void CipherSetKey(const NameValuePairs &params, const byte *key, unsigned int length) =0;
66virtual void CipherResynchronize(byte *keystreamBuffer, const byte *iv) {throw NotImplemented("StreamTransformation: this object doesn't support resynchronization");}
67virtual bool IsRandomAccess() const =0;
68virtual void SeekToIteration(dword iterationCount) {assert(!IsRandomAccess()); throw NotImplemented("StreamTransformation: this object doesn't support random access");}
69};
70
71template <typename WT, unsigned int W, unsigned int X = 1, class BASE = AdditiveCipherAbstractPolicy>
72struct AdditiveCipherConcretePolicy : public BASE
73{
74typedef WT WordType;
75
76unsigned int GetAlignment() const {return sizeof(WordType);}
77unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
78unsigned int GetIterationsToBuffer() const {return X;}
79void WriteKeystream(byte *buffer, unsigned int iterationCount)
80{OperateKeystream(WRITE_KEYSTREAM, buffer, NULL, iterationCount);}
81bool CanOperateKeystream() const {return true;}
82virtual void OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount) =0;
83
84template <class B>
85struct KeystreamOutput
86{
87KeystreamOutput(KeystreamOperation operation, byte *output, const byte *input)
88: m_operation(operation), m_output(output), m_input(input) {}
89
90inline KeystreamOutput & operator()(WordType keystreamWord)
91{
92assert(IsAligned<WordType>(m_input));
93assert(IsAligned<WordType>(m_output));
94
95if (!NativeByteOrderIs(B::ToEnum()))
96keystreamWord = ByteReverse(keystreamWord);
97
98if (m_operation == WRITE_KEYSTREAM)
99*(WordType*)m_output = keystreamWord;
100else if (m_operation == XOR_KEYSTREAM)
101{
102*(WordType*)m_output = keystreamWord ^ *(WordType*)m_input;
103m_input += sizeof(WordType);
104}
105else if (m_operation == XOR_KEYSTREAM_INPLACE)
106*(WordType*)m_output ^= keystreamWord;
107
108m_output += sizeof(WordType);
109
110return *this;
111}
112
113KeystreamOperation m_operation;
114byte *m_output;
115const byte *m_input;
116};
117};
118
119template <class BASE = AbstractPolicyHolder<AdditiveCipherAbstractPolicy, TwoBases<SymmetricCipher, RandomNumberGenerator> > >
120class AdditiveCipherTemplate : public BASE
121{
122public:
123 byte GenerateByte();
124 void ProcessData(byte *outString, const byte *inString, unsigned int length);
125void Resynchronize(const byte *iv);
126unsigned int OptimalBlockSize() const {return GetPolicy().GetBytesPerIteration();}
127unsigned int GetOptimalNextBlockSize() const {return m_leftOver;}
128unsigned int OptimalDataAlignment() const {return GetPolicy().GetAlignment();}
129bool IsSelfInverting() const {return true;}
130bool IsForwardTransformation() const {return true;}
131bool IsRandomAccess() const {return GetPolicy().IsRandomAccess();}
132void Seek(dword position);
133
134typedef typename BASE::PolicyInterface PolicyInterface;
135
136protected:
137void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length);
138
139unsigned int GetBufferByteSize(const PolicyInterface &policy) const {return policy.GetBytesPerIteration() * policy.GetIterationsToBuffer();}
140
141inline byte * KeystreamBufferBegin() {return m_buffer.data();}
142inline byte * KeystreamBufferEnd() {return (m_buffer.data() + m_buffer.size());}
143
144SecByteBlock m_buffer;
145unsigned int m_leftOver;
146};
147
148struct CFB_CipherAbstractPolicy
149{
150virtual unsigned int GetAlignment() const =0;
151virtual unsigned int GetBytesPerIteration() const =0;
152virtual byte * GetRegisterBegin() =0;
153virtual void TransformRegister() =0;
154virtual bool CanIterate() const {return false;}
155virtual void Iterate(byte *output, const byte *input, CipherDir dir, unsigned int iterationCount) {assert(false);}
156virtual void CipherSetKey(const NameValuePairs &params, const byte *key, unsigned int length) =0;
157virtual void CipherResynchronize(const byte *iv) {throw NotImplemented("StreamTransformation: this object doesn't support resynchronization");}
158};
159
160template <typename WT, unsigned int W, class BASE = CFB_CipherAbstractPolicy>
161struct CFB_CipherConcretePolicy : public BASE
162{
163typedef WT WordType;
164
165unsigned int GetAlignment() const {return sizeof(WordType);}
166unsigned int GetBytesPerIteration() const {return sizeof(WordType) * W;}
167bool CanIterate() const {return true;}
168void TransformRegister() {Iterate(NULL, NULL, ENCRYPTION, 1);}
169
170template <class B>
171struct RegisterOutput
172{
173RegisterOutput(byte *output, const byte *input, CipherDir dir)
174: m_output(output), m_input(input), m_dir(dir) {}
175
176inline RegisterOutput& operator()(WordType &registerWord)
177{
178assert(IsAligned<WordType>(m_output));
179assert(IsAligned<WordType>(m_input));
180
181if (!NativeByteOrderIs(B::ToEnum()))
182registerWord = ByteReverse(registerWord);
183
184if (m_dir == ENCRYPTION)
185{
186WordType ct = *(const WordType *)m_input ^ registerWord;
187registerWord = ct;
188*(WordType*)m_output = ct;
189m_input += sizeof(WordType);
190m_output += sizeof(WordType);
191}
192else
193{
194WordType ct = *(const WordType *)m_input;
195*(WordType*)m_output = registerWord ^ ct;
196registerWord = ct;
197m_input += sizeof(WordType);
198m_output += sizeof(WordType);
199}
200
201// registerWord is left unreversed so it can be xor-ed with further input
202
203return *this;
204}
205
206byte *m_output;
207const byte *m_input;
208CipherDir m_dir;
209};
210};
211
212template <class BASE>
213class CFB_CipherTemplate : public BASE
214{
215public:
216void ProcessData(byte *outString, const byte *inString, unsigned int length);
217void Resynchronize(const byte *iv);
218unsigned int OptimalBlockSize() const {return GetPolicy().GetBytesPerIteration();}
219unsigned int GetOptimalNextBlockSize() const {return m_leftOver;}
220unsigned int OptimalDataAlignment() const {return GetPolicy().GetAlignment();}
221bool IsRandomAccess() const {return false;}
222bool IsSelfInverting() const {return false;}
223
224typedef typename BASE::PolicyInterface PolicyInterface;
225
226protected:
227virtual void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length) =0;
228
229void UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length);
230
231unsigned int m_leftOver;
232};
233
234template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
235class CFB_EncryptionTemplate : public CFB_CipherTemplate<BASE>
236{
237bool IsForwardTransformation() const {return true;}
238void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length);
239};
240
241template <class BASE = AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >
242class CFB_DecryptionTemplate : public CFB_CipherTemplate<BASE>
243{
244bool IsForwardTransformation() const {return false;}
245void CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, unsigned int length);
246};
247
248template <class BASE, class INFO = BASE>
249class SymmetricCipherFinalTemplate : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
250{
251public:
252 SymmetricCipherFinalTemplate() {}
253SymmetricCipherFinalTemplate(const byte *key)
254{SetKey(key, DEFAULT_KEYLENGTH);}
255SymmetricCipherFinalTemplate(const byte *key, unsigned int length)
256{SetKey(key, length);}
257SymmetricCipherFinalTemplate(const byte *key, unsigned int length, const byte *iv)
258{SetKey(key, length); Resynchronize(iv);}
259
260void SetKey(const byte *key, unsigned int length, const NameValuePairs &params = g_nullNameValuePairs)
261{
262ThrowIfInvalidKeyLength(length);
263UncheckedSetKey(params, key, length);
264}
265
266Clonable * Clone() const {return static_cast<SymmetricCipher *>(new SymmetricCipherFinalTemplate<BASE, INFO>(*this));}
267};
268
269template <class S>
270void AdditiveCipherTemplate<S>::UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
271{
272PolicyInterface &policy = AccessPolicy();
273policy.CipherSetKey(params, key, length);
274m_buffer.New(GetBufferByteSize(policy));
275m_leftOver = 0;
276}
277
278template <class BASE>
279void CFB_CipherTemplate<BASE>::UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
280{
281PolicyInterface &policy = AccessPolicy();
282policy.CipherSetKey(params, key, length);
283m_leftOver = policy.GetBytesPerIteration();
284}
285
286NAMESPACE_END
287
288#endif

Archive Download this file

Branches

Tags

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