Crypto++ 8.9
Free C++ class library of cryptographic schemes
filters.cpp
1// filters.cpp - originally written and placed in the public domain by Wei Dai
2
3#include "pch.h"
4#include "config.h"
5
6#if CRYPTOPP_MSC_VERSION
7# pragma warning(disable: 4189 4355)
8#endif
9
10#ifndef CRYPTOPP_IMPORTS
11
12#include "filters.h"
13#include "mqueue.h"
14#include "fltrimpl.h"
15#include "argnames.h"
16#include "smartptr.h"
17#include "stdcpp.h"
18#include "misc.h"
19
20NAMESPACE_BEGIN(CryptoPP)
21
23 : m_attachment(attachment), m_inputPosition(0), m_continueAt(0)
24{
25}
26
27BufferedTransformation * Filter::NewDefaultAttachment() const
28{
29 return new MessageQueue;
30}
31
33{
34 if (m_attachment.get() == NULLPTR)
35 m_attachment.reset(NewDefaultAttachment());
36 return m_attachment.get();
37}
38
40{
41 if (m_attachment.get() == NULLPTR)
42 const_cast<Filter *>(this)->m_attachment.reset(NewDefaultAttachment());
43 return m_attachment.get();
44}
45
47{
48 m_attachment.reset(newOut);
49}
50
51void Filter::Insert(Filter *filter)
52{
53 filter->m_attachment.reset(m_attachment.release());
54 m_attachment.reset(filter);
55}
56
57size_t Filter::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
58{
59 return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking);
60}
61
62size_t Filter::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
63{
64 return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking);
65}
66
67void Filter::Initialize(const NameValuePairs &parameters, int propagation)
68{
69 m_inputPosition = m_continueAt = 0;
70 IsolatedInitialize(parameters);
71 PropagateInitialize(parameters, propagation);
72}
73
74bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
75{
76 switch (m_continueAt)
77 {
78 case 0:
79 if (IsolatedFlush(hardFlush, blocking))
80 return true;
81 // fall through
82 case 1:
83 if (OutputFlush(1, hardFlush, propagation, blocking))
84 return true;
85 // fall through
86 default: ;
87 }
88 return false;
89}
90
91bool Filter::MessageSeriesEnd(int propagation, bool blocking)
92{
93 switch (m_continueAt)
94 {
95 case 0:
96 if (IsolatedMessageSeriesEnd(blocking))
97 return true;
98 // fall through
99 case 1:
100 if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
101 return true;
102 // fall through
103 default: ;
104 }
105 return false;
106}
107
108void Filter::PropagateInitialize(const NameValuePairs &parameters, int propagation)
109{
110 if (propagation)
111 AttachedTransformation()->Initialize(parameters, propagation-1);
112}
113
114size_t Filter::OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel)
115{
116 if (messageEnd)
117 messageEnd--;
118 size_t result = AttachedTransformation()->ChannelPutModifiable2(channel, inString, length, messageEnd, blocking);
119 m_continueAt = result ? outputSite : 0;
120 return result;
121}
122
123size_t Filter::Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel)
124{
125 if (messageEnd)
126 messageEnd--;
127 size_t result = AttachedTransformation()->ChannelPut2(channel, inString, length, messageEnd, blocking);
128 m_continueAt = result ? outputSite : 0;
129 return result;
130}
131
132bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel)
133{
134 if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking))
135 {
136 m_continueAt = outputSite;
137 return true;
138 }
139 m_continueAt = 0;
140 return false;
141}
142
143bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel)
144{
145 if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking))
146 {
147 m_continueAt = outputSite;
148 return true;
149 }
150 m_continueAt = 0;
151 return false;
152}
153
154// *************************************************************
155
157{
158 m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0;
159 m_rangesToSkip.clear();
160}
161
162void MeterFilter::AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow)
163{
164 MessageRange r = {message, position, size};
165 m_rangesToSkip.push_back(r);
166 if (sortNow)
167 std::sort(m_rangesToSkip.begin(), m_rangesToSkip.end());
168}
169
170size_t MeterFilter::PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable)
171{
172 if (!m_transparent)
173 return 0;
174
175 size_t t;
176 FILTER_BEGIN;
177
178 m_begin = begin;
179 m_length = length;
180
181 while (m_length > 0 || messageEnd)
182 {
183 if (m_length > 0 && !m_rangesToSkip.empty() && m_rangesToSkip.front().message == m_totalMessages && m_currentMessageBytes + m_length > m_rangesToSkip.front().position)
184 {
185 FILTER_OUTPUT_MAYBE_MODIFIABLE(1, m_begin, t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position, m_currentMessageBytes), false, modifiable);
186
187 CRYPTOPP_ASSERT(t < m_length);
188 m_begin = PtrAdd(m_begin, t);
189 m_length -= t;
190 m_currentMessageBytes += t;
191 m_totalBytes += t;
192
193 if (m_currentMessageBytes + m_length < m_rangesToSkip.front().position + m_rangesToSkip.front().size)
194 t = m_length;
195 else
196 {
197 t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position + m_rangesToSkip.front().size, m_currentMessageBytes);
198 CRYPTOPP_ASSERT(t <= m_length);
199 m_rangesToSkip.pop_front();
200 }
201
202 m_begin = PtrAdd(m_begin, t);
203 m_length -= t;
204 m_currentMessageBytes += t;
205 m_totalBytes += t;
206 }
207 else
208 {
209 FILTER_OUTPUT_MAYBE_MODIFIABLE(2, m_begin, m_length, messageEnd, modifiable);
210
211 m_currentMessageBytes += m_length;
212 m_totalBytes += m_length;
213 m_length = 0;
214
215 if (messageEnd)
216 {
217 m_currentMessageBytes = 0;
218 m_currentSeriesMessages++;
219 m_totalMessages++;
220 messageEnd = false;
221 }
222 }
223 }
224
225 FILTER_END_NO_MESSAGE_END;
226}
227
228size_t MeterFilter::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
229{
230 return PutMaybeModifiable(const_cast<byte *>(begin), length, messageEnd, blocking, false);
231}
232
233size_t MeterFilter::PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
234{
235 return PutMaybeModifiable(begin, length, messageEnd, blocking, true);
236}
237
239{
240 CRYPTOPP_UNUSED(blocking);
241 m_currentMessageBytes = 0;
242 m_currentSeriesMessages = 0;
243 m_totalMessageSeries++;
244 return false;
245}
246
247// *************************************************************
248
249void FilterWithBufferedInput::BlockQueue::ResetQueue(size_t blockSize, size_t maxBlocks)
250{
251 m_buffer.New(blockSize * maxBlocks);
252 m_blockSize = blockSize;
253 m_maxBlocks = maxBlocks;
254 m_size = 0;
255 m_begin = m_buffer;
256}
257
258byte *FilterWithBufferedInput::BlockQueue::GetBlock()
259{
260 if (m_size >= m_blockSize)
261 {
262 byte *ptr = m_begin;
263 if ((m_begin = PtrAdd(m_begin, m_blockSize)) == m_buffer.end())
264 m_begin = m_buffer;
265 m_size -= m_blockSize;
266 return ptr;
267 }
268 else
269 return NULLPTR;
270}
271
272byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBytes)
273{
274 numberOfBytes = STDMIN(numberOfBytes, STDMIN<size_t>(PtrDiff(m_buffer.end(), m_begin), m_size));
275 byte *ptr = m_begin;
276 m_begin = PtrAdd(m_begin, numberOfBytes);
277 m_size -= numberOfBytes;
278 if (m_size == 0 || m_begin == m_buffer.end())
279 m_begin = m_buffer;
280 return ptr;
281}
282
283size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
284{
285 // Avoid passing NULL pointer to memcpy
286 if (!outString) return 0;
287
288 size_t size = m_size;
289 size_t numberOfBytes = m_maxBlocks*m_blockSize;
290 const byte *ptr = GetContigousBlocks(numberOfBytes);
291 std::memcpy(outString, ptr, numberOfBytes);
292 std::memcpy(PtrAdd(outString, numberOfBytes), m_begin, m_size);
293 m_size = 0;
294 return size;
295}
296
297void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length)
298{
299 // Avoid passing NULL pointer to memcpy
300 if (!inString || !length) return;
301
302 CRYPTOPP_ASSERT(m_size + length <= m_buffer.size());
303 byte *end = (m_size < static_cast<size_t>(PtrDiff(m_buffer.end(), m_begin)) ?
304 PtrAdd(m_begin, m_size) : PtrAdd(m_begin, m_size - m_buffer.size()));
305 size_t len = STDMIN(length, size_t(m_buffer.end()-end));
306 std::memcpy(end, inString, len);
307 if (len < length)
308 std::memcpy(m_buffer, PtrAdd(inString, len), length-len);
309 m_size += length;
310}
311
313 : Filter(attachment), m_firstSize(SIZE_MAX), m_blockSize(0), m_lastSize(SIZE_MAX), m_firstInputDone(false)
314{
315}
316
317FilterWithBufferedInput::FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment)
318 : Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize), m_firstInputDone(false)
319{
320 if (m_firstSize == SIZE_MAX || m_blockSize < 1 || m_lastSize == SIZE_MAX)
321 throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
322
323 m_queue.ResetQueue(1, m_firstSize);
324}
325
327{
328 InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize);
329 if (m_firstSize == SIZE_MAX || m_blockSize < 1 || m_lastSize == SIZE_MAX)
330 throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
331 m_queue.ResetQueue(1, m_firstSize);
332 m_firstInputDone = false;
333}
334
335bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking)
336{
337 if (!blocking)
338 throw BlockingInputOnly("FilterWithBufferedInput");
339
340 if (hardFlush)
341 ForceNextPut();
342 FlushDerived();
343
344 return false;
345}
346
347size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable)
348{
349 if (!blocking)
350 throw BlockingInputOnly("FilterWithBufferedInput");
351
352 if (length != 0)
353 {
354 size_t newLength = m_queue.CurrentSize() + length;
355
356 if (!m_firstInputDone && newLength >= m_firstSize)
357 {
358 size_t len = m_firstSize - m_queue.CurrentSize();
359 m_queue.Put(inString, len);
360 FirstPut(m_queue.GetContigousBlocks(m_firstSize));
361 CRYPTOPP_ASSERT(m_queue.CurrentSize() == 0);
362 m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize);
363
364 inString = PtrAdd(inString, len);
365 newLength -= m_firstSize;
366 m_firstInputDone = true;
367 }
368
369 if (m_firstInputDone)
370 {
371 if (m_blockSize == 1)
372 {
373 while (newLength > m_lastSize && m_queue.CurrentSize() > 0)
374 {
375 size_t len = newLength - m_lastSize;
376 byte *ptr = m_queue.GetContigousBlocks(len);
377 NextPutModifiable(ptr, len);
378 newLength -= len;
379 }
380
381 if (newLength > m_lastSize)
382 {
383 size_t len = newLength - m_lastSize;
384 NextPutMaybeModifiable(inString, len, modifiable);
385 inString = PtrAdd(inString, len);
386 newLength -= len;
387 }
388 }
389 else
390 {
391 while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize)
392 {
393 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
394 newLength -= m_blockSize;
395 }
396
397 if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0)
398 {
399 CRYPTOPP_ASSERT(m_queue.CurrentSize() < m_blockSize);
400 size_t len = m_blockSize - m_queue.CurrentSize();
401 m_queue.Put(inString, len);
402 inString = PtrAdd(inString, len);
403 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
404 newLength -= m_blockSize;
405 }
406
407 if (newLength >= m_blockSize + m_lastSize)
408 {
409 size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize);
410 NextPutMaybeModifiable(inString, len, modifiable);
411 inString = PtrAdd(inString, len);
412 newLength -= len;
413 }
414 }
415 }
416
417 m_queue.Put(inString, newLength - m_queue.CurrentSize());
418 }
419
420 if (messageEnd)
421 {
422 if (!m_firstInputDone && m_firstSize==0)
423 FirstPut(NULLPTR);
424
425 SecByteBlock temp(m_queue.CurrentSize());
426 m_queue.GetAll(temp);
427 LastPut(temp, temp.size());
428
429 m_firstInputDone = false;
430 m_queue.ResetQueue(1, m_firstSize);
431
432 // Cast to void to suppress Coverity finding
433 (void)Output(1, NULLPTR, 0, messageEnd, blocking);
434 }
435 return 0;
436}
437
439{
440 if (!m_firstInputDone)
441 return;
442
443 if (m_blockSize > 1)
444 {
445 while (m_queue.CurrentSize() >= m_blockSize)
446 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
447 }
448 else
449 {
450 size_t len;
451 while ((len = m_queue.CurrentSize()) > 0)
452 NextPutModifiable(m_queue.GetContigousBlocks(len), len);
453 }
454}
455
456void FilterWithBufferedInput::NextPutMultiple(const byte *inString, size_t length)
457{
458 CRYPTOPP_ASSERT(m_blockSize > 1); // m_blockSize = 1 should always override this function
459 while (length > 0)
460 {
461 CRYPTOPP_ASSERT(length >= m_blockSize);
462 NextPutSingle(inString);
463 inString = PtrAdd(inString, m_blockSize);
464 length -= m_blockSize;
465 }
466}
467
468// *************************************************************
469
470void Redirector::Initialize(const NameValuePairs &parameters, int propagation)
471{
472 m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULLPTR);
473 m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING);
474
475 if (m_target && GetPassSignals())
476 m_target->Initialize(parameters, propagation);
477}
478
479// *************************************************************
480
481ProxyFilter::ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment)
482 : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter)
483{
484 if (m_filter.get())
485 m_filter->Attach(new OutputProxy(*this, false));
486}
487
488bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking)
489{
490 return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false;
491}
492
493void ProxyFilter::SetFilter(Filter *filter)
494{
495 m_filter.reset(filter);
496 if (filter)
497 {
498 OutputProxy *proxy;
499 member_ptr<OutputProxy> temp(proxy = new OutputProxy(*this, false));
500 m_filter->TransferAllTo(*proxy);
501 m_filter->Attach(temp.release());
502 }
503}
504
505void ProxyFilter::NextPutMultiple(const byte *s, size_t len)
506{
507 if (m_filter.get())
508 m_filter->Put(s, len);
509}
510
511void ProxyFilter::NextPutModifiable(byte *s, size_t len)
512{
513 if (m_filter.get())
514 m_filter->PutModifiable(s, len);
515}
516
517// *************************************************************
518
520{
521 parameters.GetRequiredParameter("RandomNumberSink", "RandomNumberGeneratorPointer", m_rng);
522}
523
524size_t RandomNumberSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
525{
526 CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
527 m_rng->IncorporateEntropy(begin, length);
528 return 0;
529}
530
531size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
532{
533 CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
534
535 // Avoid passing NULL pointer to memcpy. Using std::memmove due to
536 // Valgrind finding on overlapping buffers.
537 size_t copied = 0;
538 if (m_buf && begin)
539 {
540 copied = STDMIN(length, SaturatingSubtract(m_size, m_total));
541 std::memmove(PtrAdd(m_buf, m_total), begin, copied);
542 }
543 m_total += copied;
544 return length - copied;
545}
546
547byte * ArraySink::CreatePutSpace(size_t &size)
548{
549 size = SaturatingSubtract(m_size, m_total);
550 return PtrAdd(m_buf, m_total);
551}
552
553void ArraySink::IsolatedInitialize(const NameValuePairs &parameters)
554{
555 ByteArrayParameter array;
556 if (!parameters.GetValue(Name::OutputBuffer(), array))
557 throw InvalidArgument("ArraySink: missing OutputBuffer argument");
558 m_buf = array.begin();
559 m_size = array.size();
560}
561
562size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
563{
564 CRYPTOPP_UNUSED(messageEnd); CRYPTOPP_UNUSED(blocking);
565
566 // Avoid passing NULL pointer to xorbuf
567 size_t copied = 0;
568 if (m_buf && begin)
569 {
570 copied = STDMIN(length, SaturatingSubtract(m_size, m_total));
571 xorbuf(PtrAdd(m_buf, m_total), begin, copied);
572 }
573 m_total += copied;
574 return length - copied;
575}
576
577// *************************************************************
578
580 : FilterWithBufferedInput(attachment), m_cipher(c), m_padding(DEFAULT_PADDING)
581{
582 CRYPTOPP_ASSERT(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
583
584 const bool authenticatedFilter = dynamic_cast<AuthenticatedSymmetricCipher *>(&c) != NULLPTR;
585 if (authenticatedFilter)
586 throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher");
587
588 // InitializeDerivedAndReturnNewSizes may override some of these
589 m_mandatoryBlockSize = m_cipher.MandatoryBlockSize();
590 m_optimalBufferSize = m_cipher.OptimalBlockSize();
591 m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1;
592 m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize);
593
596 (Name::BlockPaddingScheme(), padding));
597}
598
599StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool authenticated)
600 : FilterWithBufferedInput(attachment), m_cipher(c), m_padding(DEFAULT_PADDING)
601{
602 const bool authenticatedFilter = dynamic_cast<AuthenticatedSymmetricCipher *>(&c) != NULLPTR;
603 if (!authenticatedFilter)
604 {
605 CRYPTOPP_ASSERT(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
606 }
607
608 if (authenticatedFilter && !authenticated)
609 throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher");
610
611 // InitializeDerivedAndReturnNewSizes may override some of these
612 m_mandatoryBlockSize = m_cipher.MandatoryBlockSize();
613 m_optimalBufferSize = m_cipher.OptimalBlockSize();
614 m_isSpecial = m_cipher.IsLastBlockSpecial() && m_mandatoryBlockSize > 1;
615 m_reservedBufferSize = STDMAX(2*m_mandatoryBlockSize, m_optimalBufferSize);
616
619 (Name::BlockPaddingScheme(), padding));
620}
621
622size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding)
623{
624 if (c.MinLastBlockSize() > 0)
625 return c.MinLastBlockSize();
626 else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING)
627 return c.MandatoryBlockSize();
628
629 return 0;
630}
631
632void StreamTransformationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
633{
635 bool isBlockCipher = (m_mandatoryBlockSize > 1 && m_cipher.MinLastBlockSize() == 0);
636
637 if (padding == DEFAULT_PADDING)
638 m_padding = isBlockCipher ? PKCS_PADDING : NO_PADDING;
639 else
640 m_padding = padding;
641
642 if (!isBlockCipher)
643 {
644 if (m_padding == PKCS_PADDING)
645 throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING cannot be used with " + m_cipher.AlgorithmName());
646 else if (m_padding == W3C_PADDING)
647 throw InvalidArgument("StreamTransformationFilter: W3C_PADDING cannot be used with " + m_cipher.AlgorithmName());
648 else if (m_padding == ONE_AND_ZEROS_PADDING)
649 throw InvalidArgument("StreamTransformationFilter: ONE_AND_ZEROS_PADDING cannot be used with " + m_cipher.AlgorithmName());
650 }
651
652 firstSize = 0;
653 blockSize = m_mandatoryBlockSize;
654 lastSize = LastBlockSize(m_cipher, m_padding);
655}
656
657void StreamTransformationFilter::FirstPut(const byte* inString)
658{
659 CRYPTOPP_UNUSED(inString);
660 m_optimalBufferSize = STDMAX<unsigned int>(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
661}
662
663void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t length)
664{
665 if (!length)
666 {return;}
667
668 const size_t s = m_cipher.MandatoryBlockSize();
669 do
670 {
671 size_t len = m_optimalBufferSize;
672 byte *space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, length, len);
673 if (len < length)
674 {
675 if (len == m_optimalBufferSize)
676 len -= m_cipher.GetOptimalBlockSizeUsed();
677 len = RoundDownToMultipleOf(len, s);
678 }
679 else
680 len = length;
681 m_cipher.ProcessString(space, inString, len);
683 inString = PtrAdd(inString, len);
684 length -= len;
685 }
686 while (length > 0);
687}
688
689void StreamTransformationFilter::NextPutModifiable(byte *inString, size_t length)
690{
691 m_cipher.ProcessString(inString, length);
692 AttachedTransformation()->PutModifiable(inString, length);
693}
694
695void StreamTransformationFilter::LastPut(const byte *inString, size_t length)
696{
697 // This block is new to StreamTransformationFilter. It is somewhat of a hack and was
698 // added for OCB mode; see GitHub Issue 515. The rub with OCB is, its a block cipher
699 // and the last block size can be 0. However, "last block = 0" is not the 0 predicated
700 // in the original code. In the original code 0 means "nothing special" so
701 // DEFAULT_PADDING is applied. OCB's 0 literally means a final block size can be 0 or
702 // non-0; and no padding is needed in either case because OCB has its own scheme (see
703 // handling of P_* and A_*).
704 // Stream ciphers have policy objects to convey how to operate the cipher. The Crypto++
705 // framework operates well when MinLastBlockSize() is 1. However, it did not appear to
706 // cover the OCB case either because we can't stream OCB. It needs full block sizes. In
707 // response we hacked a IsLastBlockSpecial(). When true StreamTransformationFilter
708 // defers to the mode for processing of the last block.
709 // The behavior supplied when IsLastBlockSpecial() will likely have to evolve to capture
710 // more complex cases from different authenc modes. I suspect it will have to change
711 // from a simple bool to something that conveys more information, like "last block
712 // no padding" or "custom padding applied by cipher".
713 // In some respect we have already hit the need for more information. For example, OCB
714 // calculates the checksum on the cipher text at the same time, so we don't need the
715 // disjoint behavior of calling "EncryptBlock" followed by a separate "AuthenticateBlock".
716 // Additional information may allow us to avoid the two separate calls.
717 if (m_isSpecial)
718 {
719 const size_t leftOver = length % m_mandatoryBlockSize;
720 byte* space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, m_reservedBufferSize);
721 length -= leftOver;
722
723 if (length)
724 {
725 // Process full blocks
726 m_cipher.ProcessData(space, inString, length);
727 AttachedTransformation()->Put(space, length);
728 inString = PtrAdd(inString, length);
729 }
730
731 if (leftOver)
732 {
733 // Process final partial block
734 length = m_cipher.ProcessLastBlock(space, m_reservedBufferSize, inString, leftOver);
735 AttachedTransformation()->Put(space, length);
736 }
737 else
738 {
739 // Process final empty block
740 length = m_cipher.ProcessLastBlock(space, m_reservedBufferSize, NULLPTR, 0);
741 AttachedTransformation()->Put(space, length);
742 }
743
744 return;
745 }
746
747 switch (m_padding)
748 {
749 case NO_PADDING:
750 case ZEROS_PADDING:
751 if (length > 0)
752 {
753 const size_t minLastBlockSize = m_cipher.MinLastBlockSize();
754 const bool isForwardTransformation = m_cipher.IsForwardTransformation();
755
756 if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize))
757 {
758 // do padding
759 size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_mandatoryBlockSize);
760 byte* space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, blockSize);
761 if (inString) {std::memcpy(space, inString, length);}
762 std::memset(PtrAdd(space, length), 0, blockSize - length);
763 size_t used = m_cipher.ProcessLastBlock(space, blockSize, space, blockSize);
764 AttachedTransformation()->Put(space, used);
765 }
766 else
767 {
768 if (minLastBlockSize == 0)
769 {
770 if (isForwardTransformation)
771 throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified");
772 else
773 throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
774 }
775
776 byte* space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, length, m_optimalBufferSize);
777 size_t used = m_cipher.ProcessLastBlock(space, length, inString, length);
778 AttachedTransformation()->Put(space, used);
779 }
780 }
781 break;
782
783 case PKCS_PADDING:
784 case W3C_PADDING:
786 unsigned int s;
787 byte* space;
788 s = m_mandatoryBlockSize;
789 CRYPTOPP_ASSERT(s > 1);
790 space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, m_optimalBufferSize);
791 if (m_cipher.IsForwardTransformation())
792 {
793 CRYPTOPP_ASSERT(length < s);
794 if (inString) {std::memcpy(space, inString, length);}
795 if (m_padding == PKCS_PADDING)
796 {
797 CRYPTOPP_ASSERT(s < 256);
798 byte pad = static_cast<byte>(s-length);
799 std::memset(PtrAdd(space, length), pad, s-length);
800 }
801 else if (m_padding == W3C_PADDING)
802 {
803 CRYPTOPP_ASSERT(s < 256);
804 std::memset(PtrAdd(space, length), 0, s-length-1);
805 space[s-1] = static_cast<byte>(s-length);
806 }
807 else
808 {
809 space[length] = 0x80;
810 std::memset(PtrAdd(space, length+1), 0, s-length-1);
811 }
812 m_cipher.ProcessData(space, space, s);
813 AttachedTransformation()->Put(space, s);
814 }
815 else
816 {
817 if (length != s)
818 throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
819 m_cipher.ProcessData(space, inString, s);
820 if (m_padding == PKCS_PADDING)
821 {
822 byte pad = space[s-1];
823 if (pad < 1 || pad > s || FindIfNot(PtrAdd(space, s-pad), PtrAdd(space, s), pad) != PtrAdd(space, s))
824 throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found");
825 length = s-pad;
826 }
827 else if (m_padding == W3C_PADDING)
828 {
829 byte pad = space[s - 1];
830 if (pad < 1 || pad > s)
831 throw InvalidCiphertext("StreamTransformationFilter: invalid W3C block padding found");
832 length = s - pad;
833 }
834 else
835 {
836 while (length > 1 && space[length-1] == 0)
837 --length;
838 if (space[--length] != 0x80)
839 throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found");
840 }
841 AttachedTransformation()->Put(space, length);
842 }
843 break;
844
845 default:
846 CRYPTOPP_ASSERT(false);
847 }
848}
849
850// *************************************************************
851
852HashFilter::HashFilter(HashTransformation &hm, BufferedTransformation *attachment, bool putMessage, int truncatedDigestSize, const std::string &messagePutChannel, const std::string &hashPutChannel)
853 : m_hashModule(hm), m_putMessage(putMessage), m_digestSize(0), m_space(NULLPTR)
854 , m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel)
855{
856 m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize;
857 Detach(attachment);
858}
859
861{
862 m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
863 int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1);
864 m_digestSize = s < 0 ? m_hashModule.DigestSize() : s;
865}
866
867size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
868{
869 FILTER_BEGIN;
870 if (m_putMessage)
871 FILTER_OUTPUT3(1, 0, inString, length, 0, m_messagePutChannel);
872 if (inString && length)
873 m_hashModule.Update(inString, length);
874 if (messageEnd)
875 {
876 {
877 size_t size;
878 m_space = HelpCreatePutSpace(*AttachedTransformation(), m_hashPutChannel, m_digestSize, m_digestSize, size = m_digestSize);
879 m_hashModule.TruncatedFinal(m_space, m_digestSize);
880 }
881 FILTER_OUTPUT3(2, 0, m_space, m_digestSize, messageEnd, m_hashPutChannel);
882 }
883 FILTER_END_NO_MESSAGE_END;
884}
885
886// *************************************************************
887
889 : FilterWithBufferedInput(attachment)
890 , m_hashModule(hm), m_flags(0), m_digestSize(0), m_verified(false)
891{
895 (Name::TruncatedDigestSize(), truncatedDigestSize));
896}
897
898void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
899{
901 int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1);
902 m_digestSize = s < 0 ? m_hashModule.DigestSize() : s;
903 m_verified = false;
904 firstSize = m_flags & HASH_AT_BEGIN ? m_digestSize : 0;
905 blockSize = 1;
906 lastSize = m_flags & HASH_AT_BEGIN ? 0 : m_digestSize;
907}
908
909void HashVerificationFilter::FirstPut(const byte *inString)
910{
911 if (m_flags & HASH_AT_BEGIN)
912 {
913 m_expectedHash.New(m_digestSize);
914 if (inString) {std::memcpy(m_expectedHash, inString, m_expectedHash.size());}
915 if (m_flags & PUT_HASH)
916 AttachedTransformation()->Put(inString, m_expectedHash.size());
917 }
918}
919
920void HashVerificationFilter::NextPutMultiple(const byte *inString, size_t length)
921{
922 m_hashModule.Update(inString, length);
923 if (m_flags & PUT_MESSAGE)
924 AttachedTransformation()->Put(inString, length);
925}
926
927void HashVerificationFilter::LastPut(const byte *inString, size_t length)
928{
929 if (m_flags & HASH_AT_BEGIN)
930 {
931 CRYPTOPP_ASSERT(length == 0);
932 m_verified = m_hashModule.TruncatedVerify(m_expectedHash, m_digestSize);
933 }
934 else
935 {
936 m_verified = (length==m_digestSize && m_hashModule.TruncatedVerify(inString, length));
937 if (m_flags & PUT_HASH)
938 AttachedTransformation()->Put(inString, length);
939 }
940
941 if (m_flags & PUT_RESULT)
942 AttachedTransformation()->Put(m_verified);
943
944 if ((m_flags & THROW_EXCEPTION) && !m_verified)
945 throw HashVerificationFailed();
946}
947
948// *************************************************************
949
951 bool putAAD, int truncatedDigestSize, const std::string &macChannel, BlockPaddingScheme padding)
952 : StreamTransformationFilter(c, attachment, padding, true)
953 , m_hf(c, new OutputProxy(*this, false), putAAD, truncatedDigestSize, AAD_CHANNEL, macChannel)
954{
955 CRYPTOPP_ASSERT(c.IsForwardTransformation());
956}
957
959{
960 m_hf.IsolatedInitialize(parameters);
962}
963
964byte * AuthenticatedEncryptionFilter::ChannelCreatePutSpace(const std::string &channel, size_t &size)
965{
966 if (channel.empty())
968
969 if (channel == AAD_CHANNEL)
970 return m_hf.CreatePutSpace(size);
971
972 throw InvalidChannelName("AuthenticatedEncryptionFilter", channel);
973}
974
975size_t AuthenticatedEncryptionFilter::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
976{
977 if (channel.empty())
978 return StreamTransformationFilter::Put2(begin, length, messageEnd, blocking);
979
980 if (channel == AAD_CHANNEL)
981 return m_hf.Put2(begin, length, 0, blocking);
982
983 throw InvalidChannelName("AuthenticatedEncryptionFilter", channel);
984}
985
986void AuthenticatedEncryptionFilter::LastPut(const byte *inString, size_t length)
987{
988 StreamTransformationFilter::LastPut(inString, length);
989 m_hf.MessageEnd();
990}
991
992// *************************************************************
993
994AuthenticatedDecryptionFilter::AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize, BlockPaddingScheme padding)
995 : FilterWithBufferedInput(attachment)
996 , m_hashVerifier(c, new OutputProxy(*this, false))
997 , m_streamFilter(c, new OutputProxy(*this, false), padding, true)
998{
999 CRYPTOPP_ASSERT(!c.IsForwardTransformation() || c.IsSelfInverting());
1002 (Name::BlockPaddingScheme(), padding)
1004 (Name::TruncatedDigestSize(), truncatedDigestSize));
1005}
1006
1007void AuthenticatedDecryptionFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
1008{
1010
1012 m_streamFilter.Initialize(parameters);
1013
1014 firstSize = m_hashVerifier.m_firstSize;
1015 blockSize = 1;
1016 lastSize = m_hashVerifier.m_lastSize;
1017}
1018
1019byte * AuthenticatedDecryptionFilter::ChannelCreatePutSpace(const std::string &channel, size_t &size)
1020{
1021 if (channel.empty())
1022 return m_streamFilter.CreatePutSpace(size);
1023
1024 if (channel == AAD_CHANNEL)
1025 return m_hashVerifier.CreatePutSpace(size);
1026
1027 throw InvalidChannelName("AuthenticatedDecryptionFilter", channel);
1028}
1029
1030size_t AuthenticatedDecryptionFilter::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
1031{
1032 if (channel.empty())
1033 {
1034 if (m_lastSize > 0)
1035 m_hashVerifier.ForceNextPut();
1036 return FilterWithBufferedInput::Put2(begin, length, messageEnd, blocking);
1037 }
1038
1039 if (channel == AAD_CHANNEL)
1040 return m_hashVerifier.Put2(begin, length, 0, blocking);
1041
1042 throw InvalidChannelName("AuthenticatedDecryptionFilter", channel);
1043}
1044
1045void AuthenticatedDecryptionFilter::FirstPut(const byte *inString)
1046{
1047 m_hashVerifier.Put(inString, m_firstSize);
1048}
1049
1050void AuthenticatedDecryptionFilter::NextPutMultiple(const byte *inString, size_t length)
1051{
1052 m_streamFilter.Put(inString, length);
1053}
1054
1055void AuthenticatedDecryptionFilter::LastPut(const byte *inString, size_t length)
1056{
1057 m_streamFilter.MessageEnd();
1058 m_hashVerifier.PutMessageEnd(inString, length);
1059}
1060
1061// *************************************************************
1062
1064{
1065 m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
1066 m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
1067}
1068
1069size_t SignerFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
1070{
1071 FILTER_BEGIN;
1072 m_messageAccumulator->Update(inString, length);
1073 if (m_putMessage)
1074 FILTER_OUTPUT(1, inString, length, 0);
1075 if (messageEnd)
1076 {
1077 m_buf.New(m_signer.SignatureLength());
1078 m_signer.Sign(m_rng, m_messageAccumulator.release(), m_buf);
1079 FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd);
1080 m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
1081 }
1082 FILTER_END_NO_MESSAGE_END;
1083}
1084
1086 : FilterWithBufferedInput(attachment)
1087 , m_verifier(verifier), m_flags(0), m_verified(0)
1088{
1092}
1093
1094void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
1095{
1097 m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator());
1098 size_t size = m_verifier.SignatureLength();
1099 CRYPTOPP_ASSERT(size != 0); // TODO: handle recoverable signature scheme
1100 m_verified = false;
1101 firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0;
1102 blockSize = 1;
1103 lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size;
1104}
1105
1106void SignatureVerificationFilter::FirstPut(const byte *inString)
1107{
1108 if (m_flags & SIGNATURE_AT_BEGIN)
1109 {
1110 if (m_verifier.SignatureUpfront())
1111 m_verifier.InputSignature(*m_messageAccumulator, inString, m_verifier.SignatureLength());
1112 else
1113 {
1114 m_signature.New(m_verifier.SignatureLength());
1115 if (inString) {std::memcpy(m_signature, inString, m_signature.size());}
1116 }
1117
1118 if (m_flags & PUT_SIGNATURE)
1119 AttachedTransformation()->Put(inString, m_signature.size());
1120 }
1121 else
1122 {
1123 CRYPTOPP_ASSERT(!m_verifier.SignatureUpfront());
1124 }
1125}
1126
1127void SignatureVerificationFilter::NextPutMultiple(const byte *inString, size_t length)
1128{
1129 m_messageAccumulator->Update(inString, length);
1130 if (m_flags & PUT_MESSAGE)
1131 AttachedTransformation()->Put(inString, length);
1132}
1133
1134void SignatureVerificationFilter::LastPut(const byte *inString, size_t length)
1135{
1136 if (m_flags & SIGNATURE_AT_BEGIN)
1137 {
1138 CRYPTOPP_ASSERT(length == 0);
1139 m_verifier.InputSignature(*m_messageAccumulator, m_signature, m_signature.size());
1140 m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator);
1141 }
1142 else
1143 {
1144 m_verifier.InputSignature(*m_messageAccumulator, inString, length);
1145 m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator);
1146 if (m_flags & PUT_SIGNATURE)
1147 AttachedTransformation()->Put(inString, length);
1148 }
1149
1150 if (m_flags & PUT_RESULT)
1151 AttachedTransformation()->Put(m_verified);
1152
1153 if ((m_flags & THROW_EXCEPTION) && !m_verified)
1154 throw SignatureVerificationFailed();
1155}
1156
1157// *************************************************************
1158
1159size_t Source::PumpAll2(bool blocking)
1160{
1161 unsigned int messageCount = UINT_MAX;
1162 do {
1163 RETURN_IF_NONZERO(PumpMessages2(messageCount, blocking));
1164 } while(messageCount == UINT_MAX);
1165
1166 return 0;
1167}
1168
1170{
1171 if (!m_messageEnd && !AnyRetrievable())
1172 {
1173 m_messageEnd=true;
1174 return true;
1175 }
1176 else
1177 return false;
1178}
1179
1180unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
1181{
1182 if (m_messageEnd || count == 0)
1183 return 0;
1184 else
1185 {
1186 CopyTo(target, ULONG_MAX, channel);
1188 target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
1189 return 1;
1190 }
1191}
1192
1193void StringStore::StoreInitialize(const NameValuePairs &parameters)
1194{
1196 if (!parameters.GetValue(Name::InputBuffer(), array))
1197 throw InvalidArgument("StringStore: missing InputBuffer argument");
1198 m_store = array.begin();
1199 m_length = array.size();
1200 m_count = 0;
1201}
1202
1203size_t StringStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
1204{
1205 lword position = 0;
1206 size_t blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
1207 m_count += static_cast<size_t>(position);
1208 transferBytes = position;
1209 return blockedBytes;
1210}
1211
1212size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
1213{
1214 size_t i = UnsignedMin(m_length, m_count+begin);
1215 size_t len = UnsignedMin(m_length-i, end-begin);
1216 size_t blockedBytes = target.ChannelPut2(channel, PtrAdd(m_store, i), len, 0, blocking);
1217 if (!blockedBytes)
1218 begin = PtrAdd(begin, len);
1219 return blockedBytes;
1220}
1221
1222void RandomNumberStore::StoreInitialize(const NameValuePairs &parameters)
1223{
1224 parameters.GetRequiredParameter("RandomNumberStore", "RandomNumberGeneratorPointer", m_rng);
1225 int length;
1226 parameters.GetRequiredIntParameter("RandomNumberStore", "RandomNumberStoreSize", length);
1227 m_length = length;
1228}
1229
1230size_t RandomNumberStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
1231{
1232 if (!blocking)
1233 throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
1234
1235 transferBytes = UnsignedMin(transferBytes, m_length - m_count);
1236 m_rng->GenerateIntoBufferedTransformation(target, channel, transferBytes);
1237 m_count += transferBytes;
1238
1239 return 0;
1240}
1241
1242size_t NullStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
1243{
1244 static const byte nullBytes[128] = {0};
1245 while (begin < end)
1246 {
1247 size_t len = (size_t)STDMIN(end-begin, lword(128));
1248 size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
1249 if (blockedBytes)
1250 return blockedBytes;
1251 begin = PtrAdd(begin, len);
1252 }
1253 return 0;
1254}
1255
1256size_t NullStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
1257{
1258 lword begin = 0;
1259 size_t blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking);
1260 transferBytes = begin; m_size -= begin;
1261 return blockedBytes;
1262}
1263
1264NAMESPACE_END
1265
1266#endif
AlgorithmParameters MakeParameters(const char *name, const T &value, bool throwIfNotUsed=true)
Create an object that implements NameValuePairs.
Definition algparam.h:508
Standard names for retrieving values by name when working with NameValuePairs.
virtual std::string AlgorithmName() const
Provides the name of this algorithm.
Definition cryptlib.h:624
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
byte * CreatePutSpace(size_t &size)
Request space which can be written into by the caller.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
@ DEFAULT_FLAGS
Default flags using THROW_EXCEPTION.
Definition filters.h:745
AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment=NULL, word32 flags=DEFAULT_FLAGS, int truncatedDigestSize=-1, BlockPaddingScheme padding=DEFAULT_PADDING)
Construct a AuthenticatedDecryptionFilter.
size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing on a channel.
byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
Request space which can be written into by the caller.
size_t ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing on a channel.
void LastPut(const byte *inString, size_t length)
Input the last block of data.
byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
Request space which can be written into by the caller.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment=NULL, bool putAAD=false, int truncatedDigestSize=-1, const std::string &macChannel=DEFAULT_CHANNEL, BlockPaddingScheme padding=DEFAULT_PADDING)
Construct a AuthenticatedEncryptionFilter.
Interface for authenticated encryption modes of operation.
Definition cryptlib.h:1326
int GetAutoSignalPropagation() const
Retrieve automatic signal propagation value.
Definition simple.h:439
Interface for buffered transformations.
Definition cryptlib.h:1657
virtual bool AnyRetrievable() const
Determines whether bytes are ready for retrieval.
virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
Initialize or reinitialize this object, with signal propagation.
bool MessageEnd(int propagation=-1, bool blocking=true)
Signals the end of messages to the object.
Definition cryptlib.h:1748
virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)=0
Transfer bytes from this object to another BufferedTransformation.
virtual bool ChannelFlush(const std::string &channel, bool hardFlush, int propagation=-1, bool blocking=true)
Flush buffered input and/or output on a channel.
virtual void Attach(BufferedTransformation *newAttachment)
Add newAttachment to the end of attachment chain.
virtual size_t ChannelPutModifiable2(const std::string &channel, byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes that may be modified by callee on a channel.
virtual bool IsolatedFlush(bool hardFlush, bool blocking)=0
Flushes data buffered by this object, without signal propagation.
lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
Copy bytes from this object to another BufferedTransformation.
Definition cryptlib.h:2018
virtual void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Definition cryptlib.h:1821
virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0
Copy bytes from this object to another BufferedTransformation.
void TransferAllTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL)
Transfer all bytes from this object to another BufferedTransformation.
Definition cryptlib.h:2098
virtual size_t ChannelPut2(const std::string &channel, const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing on a channel.
virtual byte * CreatePutSpace(size_t &size)
Request space which can be written into by the caller.
Definition cryptlib.h:1725
size_t PutMessageEnd(const byte *inString, size_t length, int propagation=-1, bool blocking=true)
Input multiple bytes for processing and signal the end of a message.
Definition cryptlib.h:1762
virtual bool IsolatedMessageSeriesEnd(bool blocking)
Marks the end of a series of messages, without signal propagation.
Definition cryptlib.h:1837
virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
Flush buffered input and/or output, with signal propagation.
virtual bool ChannelMessageSeriesEnd(const std::string &channel, int propagation=-1, bool blocking=true)
Marks the end of a series of messages on a channel.
virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)=0
Input multiple bytes for processing.
bool ChannelMessageEnd(const std::string &channel, int propagation=-1, bool blocking=true)
Signal the end of a message.
Definition cryptlib.h:2257
size_t PutModifiable(byte *inString, size_t length, bool blocking=true)
Input multiple bytes that may be modified by callee.
Definition cryptlib.h:1740
size_t Put(byte inByte, bool blocking=true)
Input a byte for processing.
Definition cryptlib.h:1678
Used to pass byte array input as part of a NameValuePairs object.
Definition algparam.h:99
byte * begin() const
Pointer to the first byte in the memory block.
Definition algparam.h:113
size_t size() const
Length of the memory block.
Definition algparam.h:117
Combines two sets of NameValuePairs.
Definition algparam.h:129
Used to pass byte array input as part of a NameValuePairs object.
Definition algparam.h:25
const byte * begin() const
Pointer to the first byte in the memory block.
Definition algparam.h:84
size_t size() const
Length of the memory block.
Definition algparam.h:88
Implementation of BufferedTransformation's attachment interface.
Definition filters.h:36
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
Initialize or reinitialize this object, with signal propagation.
Filter(BufferedTransformation *attachment=NULL)
Construct a Filter.
void Detach(BufferedTransformation *newAttachment=NULL)
Replace an attached transformation.
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
Marks the end of a series of messages, with signal propagation.
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
Flush buffered input and/or output, with signal propagation.
Divides an input stream into discrete blocks.
Definition filters.h:342
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
FilterWithBufferedInput(BufferedTransformation *attachment)
Construct a FilterWithBufferedInput with an attached transformation.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
Definition filters.h:359
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
void ForceNextPut()
Flushes data buffered by this object.
byte * CreatePutSpace(size_t &size)
Request space which can be written into by the caller.
Definition filters.h:598
HashFilter(HashTransformation &hm, BufferedTransformation *attachment=NULL, bool putMessage=false, int truncatedDigestSize=-1, const std::string &messagePutChannel=DEFAULT_CHANNEL, const std::string &hashPutChannel=DEFAULT_CHANNEL)
Construct a HashFilter.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
Interface for hash functions and data processing part of MACs.
Definition cryptlib.h:1118
virtual void TruncatedFinal(byte *digest, size_t digestSize)=0
Computes the hash of the current message.
virtual unsigned int DigestSize() const =0
Provides the digest size of the hash.
virtual void Update(const byte *input, size_t length)=0
Updates a hash with additional input.
virtual bool TruncatedVerify(const byte *digest, size_t digestLength)
Verifies the hash of the current message.
HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment=NULL, word32 flags=DEFAULT_FLAGS, int truncatedDigestSize=-1)
Construct a HashVerificationFilter.
@ DEFAULT_FLAGS
Default flags using HASH_AT_BEGIN and PUT_RESULT.
Definition filters.h:640
@ HASH_AT_BEGIN
The hash is at the beginning of the message (i.e., concatenation of hash+message)
Definition filters.h:630
@ THROW_EXCEPTION
The filter should throw a HashVerificationFailed if a failure is encountered.
Definition filters.h:638
@ PUT_HASH
The hash should be passed to an attached transformation.
Definition filters.h:634
@ PUT_MESSAGE
The message should be passed to an attached transformation.
Definition filters.h:632
@ PUT_RESULT
The result of the verification should be passed to an attached transformation.
Definition filters.h:636
An invalid argument was detected.
Definition cryptlib.h:208
A decryption filter encountered invalid ciphertext.
Definition cryptlib.h:228
Input data was received that did not conform to expected format.
Definition cryptlib.h:218
Data structure used to store messages.
Definition mqueue.h:24
size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes that may be modified by callee.
void AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow=true)
Adds a range to skip during processing.
void ResetMeter()
Resets the meter.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
bool IsolatedMessageSeriesEnd(bool blocking)
Marks the end of a series of messages, without signal propagation.
Interface for retrieving values given their names.
Definition cryptlib.h:327
T GetValueWithDefault(const char *name, T defaultValue) const
Get a named value.
Definition cryptlib.h:397
bool GetValue(const char *name, T &value) const
Get a named value.
Definition cryptlib.h:384
CRYPTOPP_DLL int GetIntValueWithDefault(const char *name, int defaultValue) const
Get a named value with type int, with default.
Definition cryptlib.h:429
CRYPTOPP_DLL void GetRequiredIntParameter(const char *className, const char *name, int &value) const
Retrieves a required name/value pair.
Definition cryptlib.h:488
void GetRequiredParameter(const char *className, const char *name, T &value) const
Retrieves a required name/value pair.
Definition cryptlib.h:473
A method was called which was not implemented.
Definition cryptlib.h:238
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
Filter class that is a proxy for a sink.
Definition filters.h:991
Interface for public-key signature verifiers.
Definition cryptlib.h:2946
ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment)
Construct a ProxyFilter.
void SetFilter(Filter *filter)
Sets the OutputProxy filter.
bool IsolatedFlush(bool hardFlush, bool blocking)
Flushes data buffered by this object, without signal propagation.
virtual void IncorporateEntropy(const byte *input, size_t length)
Update RNG state with additional unpredictable values.
Definition cryptlib.h:1452
virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
Generate random bytes into a BufferedTransformation.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
@ PASS_EVERYTHING
Pass everything.
Definition filters.h:898
bool GetPassSignals() const
Retrieve signal propagation behavior.
Definition filters.h:926
void Initialize(const NameValuePairs &parameters, int propagation)
Initialize or reinitialize this object, with signal propagation.
void New(size_type newSize)
Change size without preserving contents.
Definition secblock.h:1126
size_type size() const
Provides the count of elements in the SecBlock.
Definition secblock.h:867
SecBlock typedef.
Definition secblock.h:1226
@ SIGNATURE_AT_BEGIN
The signature is at the beginning of the message (i.e., concatenation of signature+message)
Definition filters.h:840
@ THROW_EXCEPTION
The filter should throw a HashVerificationFailed if a failure is encountered.
Definition filters.h:848
@ DEFAULT_FLAGS
Default flags using SIGNATURE_AT_BEGIN and PUT_RESULT.
Definition filters.h:850
@ PUT_MESSAGE
The message should be passed to an attached transformation.
Definition filters.h:842
@ PUT_RESULT
The result of the verification should be passed to an attached transformation.
Definition filters.h:846
@ PUT_SIGNATURE
The signature should be passed to an attached transformation.
Definition filters.h:844
SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment=NULL, word32 flags=DEFAULT_FLAGS)
Construct a SignatureVerificationFilter.
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
Input multiple bytes for processing.
void IsolatedInitialize(const NameValuePairs &parameters)
Initialize or reinitialize this object, without signal propagation.
virtual size_t PumpMessages2(unsigned int &messageCount, bool blocking=true)=0
Pump messages to attached transformation.
virtual size_t PumpAll2(bool blocking=true)
Pump all data to attached transformation.
bool GetNextMessage()
Start retrieving the next message.
Filter wrapper for StreamTransformation.
Definition filters.h:532
StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment=NULL, BlockPaddingScheme padding=DEFAULT_PADDING)
Construct a StreamTransformationFilter.
Interface for the data processing portion of stream ciphers.
Definition cryptlib.h:951
virtual unsigned int MinLastBlockSize() const
Provides the size of the last block.
Definition cryptlib.h:1026
virtual void ProcessData(byte *outString, const byte *inString, size_t length)=0
Encrypt or decrypt an array of bytes.
virtual bool IsForwardTransformation() const =0
Determines if the cipher is being operated in its forward direction.
virtual size_t ProcessLastBlock(byte *outString, size_t outLength, const byte *inString, size_t inLength)
Encrypt or decrypt the last block of data.
virtual unsigned int GetOptimalBlockSizeUsed() const
Provides the number of bytes used in the current block when processing at optimal block size.
Definition cryptlib.h:981
void ProcessString(byte *inoutString, size_t length)
Encrypt or decrypt a string of bytes.
Definition cryptlib.h:1065
virtual unsigned int MandatoryBlockSize() const
Provides the mandatory block size of the cipher.
Definition cryptlib.h:970
CRYPTOPP_DLL size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
Copy bytes from this object to another BufferedTransformation.
CRYPTOPP_DLL size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
Transfer bytes from this object to another BufferedTransformation.
Pointer that overloads operator ->
Definition smartptr.h:38
Library configuration file.
unsigned int word32
32-bit unsigned datatype
Definition config_int.h:72
word64 lword
Large word type.
Definition config_int.h:168
const std::string DEFAULT_CHANNEL
Default channel for BufferedTransformation.
Definition cryptlib.h:516
const std::string AAD_CHANNEL
Channel for additional authenticated data.
Definition cryptlib.h:525
Implementation of BufferedTransformation's attachment interface.
Utility functions for the Crypto++ library.
T1 SaturatingSubtract(const T1 &a, const T2 &b)
Performs a saturating subtract clamped at 0.
Definition misc.h:1302
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
Definition misc.h:668
#define SIZE_MAX
The maximum value of a machine word.
Definition misc.h:120
const T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition misc.h:657
ptrdiff_t PtrDiff(const PTR pointer1, const PTR pointer2)
Determine pointer difference.
Definition misc.h:416
T1 RoundDownToMultipleOf(const T1 &n, const T2 &m)
Rounds a value down to a multiple of a second value.
Definition misc.h:1354
InputIt FindIfNot(InputIt first, InputIt last, const T &value)
Finds first element not in a range.
Definition misc.h:3190
PTR PtrAdd(PTR pointer, OFF offset)
Create a pointer with an offset.
Definition misc.h:388
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be negative and incorrectly promoted.
Definition misc.h:695
CRYPTOPP_DLL void xorbuf(byte *buf, const byte *mask, size_t count)
Performs an XOR of a buffer with a mask.
Classes for an unlimited queue to store messages.
Crypto++ library namespace.
const char * InputBuffer()
ConstByteArrayParameter.
Definition argnames.h:56
const char * TruncatedDigestSize()
int
Definition argnames.h:51
const char * AuthenticatedDecryptionFilterFlags()
word32
Definition argnames.h:54
const char * PutMessage()
bool
Definition argnames.h:50
const char * OutputBuffer()
ByteArrayParameter.
Definition argnames.h:57
const char * HashVerificationFilterFlags()
word32
Definition argnames.h:53
const char * BlockPaddingScheme()
StreamTransformationFilter::BlockPaddingScheme.
Definition argnames.h:52
const char * SignatureVerificationFilterFlags()
word32
Definition argnames.h:55
Precompiled header file.
Classes for automatic resource management.
Common C++ header files.
BlockPaddingScheme
Padding schemes used for block ciphers.
Definition filters.h:501
@ DEFAULT_PADDING
Default padding scheme.
Definition filters.h:521
@ W3C_PADDING
W3C padding added to a block.
Definition filters.h:518
@ PKCS_PADDING
PKCS padding added to a block.
Definition filters.h:510
@ ONE_AND_ZEROS_PADDING
1 and 0's padding added to a block
Definition filters.h:513
@ NO_PADDING
No padding added to a block.
Definition filters.h:504
@ ZEROS_PADDING
0's padding added to a block
Definition filters.h:507
byte * HelpCreatePutSpace(BufferedTransformation &target, const std::string &channel, size_t minSize, size_t desiredSize, size_t &bufferSize)
Create a working space in a BufferedTransformation.
Definition filters.h:187
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition trap.h:68