monotone

monotone Mtn Source Tree

Root/cryptopp/modes.cpp

1// modes.cpp - written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "modes.h"
5
6#include "des.h"
7
8#include "strciphr.cpp"
9
10NAMESPACE_BEGIN(CryptoPP)
11
12void Modes_TestInstantiations()
13{
14CFB_Mode<DES>::Encryption m0;
15CFB_Mode<DES>::Decryption m1;
16OFB_Mode<DES>::Encryption m2;
17CTR_Mode<DES>::Encryption m3;
18ECB_Mode<DES>::Encryption m4;
19CBC_Mode<DES>::Encryption m5;
20}
21
22// explicit instantiations for Darwin gcc-932.1
23template class CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, SymmetricCipher> >;
24template class CFB_EncryptionTemplate<>;
25template class CFB_DecryptionTemplate<>;
26template class AdditiveCipherTemplate<>;
27template class CFB_CipherTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
28template class CFB_EncryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
29template class CFB_DecryptionTemplate<AbstractPolicyHolder<CFB_CipherAbstractPolicy, CFB_ModePolicy> >;
30template class AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, OFB_ModePolicy> >;
31template class AdditiveCipherTemplate<AbstractPolicyHolder<AdditiveCipherAbstractPolicy, CTR_ModePolicy> >;
32
33void CipherModeBase::SetKey(const byte *key, unsigned int length, const NameValuePairs &params)
34{
35UncheckedSetKey(params, key, length);// the underlying cipher will check the key length
36}
37
38void CipherModeBase::GetNextIV(byte *IV)
39{
40if (!IsForwardTransformation())
41throw NotImplemented("CipherModeBase: GetNextIV() must be called on an encryption object");
42
43m_cipher->ProcessBlock(m_register);
44memcpy(IV, m_register, BlockSize());
45}
46
47void CipherModeBase::SetIV(const byte *iv)
48{
49if (iv)
50Resynchronize(iv);
51else if (IsResynchronizable())
52{
53if (!CanUseStructuredIVs())
54throw InvalidArgument("CipherModeBase: this cipher mode cannot use a null IV");
55
56// use all zeros as default IV
57SecByteBlock iv(BlockSize());
58memset(iv, 0, iv.size());
59Resynchronize(iv);
60}
61}
62
63void CTR_ModePolicy::SeekToIteration(dword iterationCount)
64{
65int carry=0;
66for (int i=BlockSize()-1; i>=0; i--)
67{
68unsigned int sum = m_register[i] + byte(iterationCount) + carry;
69m_counterArray[i] = (byte) sum;
70carry = sum >> 8;
71iterationCount >>= 8;
72}
73}
74
75static inline void IncrementCounterByOne(byte *inout, unsigned int s)
76{
77for (int i=s-1, carry=1; i>=0 && carry; i--)
78carry = !++inout[i];
79}
80
81static inline void IncrementCounterByOne(byte *output, const byte *input, unsigned int s)
82{
83for (int i=s-1, carry=1; i>=0; i--)
84carry = !(output[i] = input[i]+carry) && carry;
85}
86
87inline void CTR_ModePolicy::ProcessMultipleBlocks(byte *output, const byte *input, unsigned int n)
88{
89unsigned int s = BlockSize(), j = 0;
90for (unsigned int i=1; i<n; i++, j+=s)
91IncrementCounterByOne(m_counterArray + j + s, m_counterArray + j, s);
92m_cipher->ProcessAndXorMultipleBlocks(m_counterArray, input, output, n);
93IncrementCounterByOne(m_counterArray, m_counterArray + s*(n-1), s);
94}
95
96void CTR_ModePolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, unsigned int iterationCount)
97{
98unsigned int maxBlocks = m_cipher->OptimalNumberOfParallelBlocks();
99if (maxBlocks == 1)
100{
101unsigned int sizeIncrement = BlockSize();
102while (iterationCount)
103{
104m_cipher->ProcessAndXorBlock(m_counterArray, input, output);
105IncrementCounterByOne(m_counterArray, sizeIncrement);
106output += sizeIncrement;
107input += sizeIncrement;
108iterationCount -= 1;
109}
110}
111else
112{
113unsigned int sizeIncrement = maxBlocks * BlockSize();
114while (iterationCount >= maxBlocks)
115{
116ProcessMultipleBlocks(output, input, maxBlocks);
117output += sizeIncrement;
118input += sizeIncrement;
119iterationCount -= maxBlocks;
120}
121if (iterationCount > 0)
122ProcessMultipleBlocks(output, input, iterationCount);
123}
124}
125
126void CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv)
127{
128unsigned int s = BlockSize();
129memcpy(m_register, iv, s);
130m_counterArray.New(s * m_cipher->OptimalNumberOfParallelBlocks());
131memcpy(m_counterArray, iv, s);
132}
133
134void BlockOrientedCipherModeBase::UncheckedSetKey(const NameValuePairs &params, const byte *key, unsigned int length)
135{
136m_cipher->SetKey(key, length, params);
137ResizeBuffers();
138const byte *iv = params.GetValueWithDefault(Name::IV(), (const byte *)NULL);
139SetIV(iv);
140}
141
142void BlockOrientedCipherModeBase::ProcessData(byte *outString, const byte *inString, unsigned int length)
143{
144unsigned int s = BlockSize();
145assert(length % s == 0);
146unsigned int alignment = m_cipher->BlockAlignment();
147bool inputAlignmentOk = !RequireAlignedInput() || IsAlignedOn(inString, alignment);
148
149if (IsAlignedOn(outString, alignment))
150{
151if (inputAlignmentOk)
152ProcessBlocks(outString, inString, length / s);
153else
154{
155memcpy(outString, inString, length);
156ProcessBlocks(outString, outString, length / s);
157}
158}
159else
160{
161while (length)
162{
163if (inputAlignmentOk)
164ProcessBlocks(m_buffer, inString, 1);
165else
166{
167memcpy(m_buffer, inString, s);
168ProcessBlocks(m_buffer, m_buffer, 1);
169}
170memcpy(outString, m_buffer, s);
171inString += s;
172outString += s;
173length -= s;
174}
175}
176}
177
178void CBC_Encryption::ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks)
179{
180unsigned int blockSize = BlockSize();
181while (numberOfBlocks--)
182{
183xorbuf(m_register, inString, blockSize);
184m_cipher->ProcessBlock(m_register);
185memcpy(outString, m_register, blockSize);
186inString += blockSize;
187outString += blockSize;
188}
189}
190
191void CBC_CTS_Encryption::ProcessLastBlock(byte *outString, const byte *inString, unsigned int length)
192{
193if (length <= BlockSize())
194{
195if (!m_stolenIV)
196throw InvalidArgument("CBC_Encryption: message is too short for ciphertext stealing");
197
198// steal from IV
199memcpy(outString, m_register, length);
200outString = m_stolenIV;
201}
202else
203{
204// steal from next to last block
205xorbuf(m_register, inString, BlockSize());
206m_cipher->ProcessBlock(m_register);
207inString += BlockSize();
208length -= BlockSize();
209memcpy(outString+BlockSize(), m_register, length);
210}
211
212// output last full ciphertext block
213xorbuf(m_register, inString, length);
214m_cipher->ProcessBlock(m_register);
215memcpy(outString, m_register, BlockSize());
216}
217
218void CBC_Decryption::ProcessBlocks(byte *outString, const byte *inString, unsigned int numberOfBlocks)
219{
220unsigned int blockSize = BlockSize();
221while (numberOfBlocks--)
222{
223memcpy(m_temp, inString, blockSize);
224m_cipher->ProcessBlock(m_temp, outString);
225xorbuf(outString, m_register, blockSize);
226m_register.swap(m_temp);
227inString += blockSize;
228outString += blockSize;
229}
230}
231
232void CBC_CTS_Decryption::ProcessLastBlock(byte *outString, const byte *inString, unsigned int length)
233{
234const byte *pn, *pn1;
235bool stealIV = length <= BlockSize();
236
237if (stealIV)
238{
239pn = inString;
240pn1 = m_register;
241}
242else
243{
244pn = inString + BlockSize();
245pn1 = inString;
246length -= BlockSize();
247}
248
249// decrypt last partial plaintext block
250memcpy(m_temp, pn1, BlockSize());
251m_cipher->ProcessBlock(m_temp);
252xorbuf(m_temp, pn, length);
253
254if (stealIV)
255memcpy(outString, m_temp, length);
256else
257{
258memcpy(outString+BlockSize(), m_temp, length);
259// decrypt next to last plaintext block
260memcpy(m_temp, pn, length);
261m_cipher->ProcessBlock(m_temp);
262xorbuf(outString, m_temp, m_register, BlockSize());
263}
264}
265
266NAMESPACE_END

Archive Download this file

Branches

Tags

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