Crypto++  8.8
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 
20 NAMESPACE_BEGIN(CryptoPP)
21 
23  : m_attachment(attachment), m_inputPosition(0), m_continueAt(0)
24 {
25 }
26 
27 BufferedTransformation * 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 
51 void Filter::Insert(Filter *filter)
52 {
53  filter->m_attachment.reset(m_attachment.release());
54  m_attachment.reset(filter);
55 }
56 
57 size_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 
62 size_t Filter::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
63 {
64  return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking);
65 }
66 
67 void Filter::Initialize(const NameValuePairs &parameters, int propagation)
68 {
69  m_inputPosition = m_continueAt = 0;
70  IsolatedInitialize(parameters);
71  PropagateInitialize(parameters, propagation);
72 }
73 
74 bool 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 
91 bool 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 
108 void Filter::PropagateInitialize(const NameValuePairs &parameters, int propagation)
109 {
110  if (propagation)
111  AttachedTransformation()->Initialize(parameters, propagation-1);
112 }
113 
114 size_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 
123 size_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 
132 bool 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 
143 bool 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 
162 void 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 
170 size_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 
228 size_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 
233 size_t MeterFilter::PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
234 {
235  return PutMaybeModifiable(begin, length, messageEnd, blocking, true);
236 }
237 
238 bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking)
239 {
240  CRYPTOPP_UNUSED(blocking);
241  m_currentMessageBytes = 0;
242  m_currentSeriesMessages = 0;
243  m_totalMessageSeries++;
244  return false;
245 }
246 
247 // *************************************************************
248 
249 void 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 
258 byte *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 
272 byte *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 
283 size_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 
297 void 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 
317 FilterWithBufferedInput::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 
335 bool 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 
347 size_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 
456 void 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 
470 void 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 
481 ProxyFilter::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 
488 bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking)
489 {
490  return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false;
491 }
492 
493 void 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 
505 void ProxyFilter::NextPutMultiple(const byte *s, size_t len)
506 {
507  if (m_filter.get())
508  m_filter->Put(s, len);
509 }
510 
511 void 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 
524 size_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 
531 size_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 
547 byte * ArraySink::CreatePutSpace(size_t &size)
548 {
549  size = SaturatingSubtract(m_size, m_total);
550  return PtrAdd(m_buf, m_total);
551 }
552 
553 void 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 
562 size_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 
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 
622 size_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 
632 void 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 
657 void StreamTransformationFilter::FirstPut(const byte* inString)
658 {
659  CRYPTOPP_UNUSED(inString);
660  m_optimalBufferSize = STDMAX<unsigned int>(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
661 }
662 
663 void 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);
682  AttachedTransformation()->PutModifiable(space, len);
683  inString = PtrAdd(inString, len);
684  length -= len;
685  }
686  while (length > 0);
687 }
688 
689 void StreamTransformationFilter::NextPutModifiable(byte *inString, size_t length)
690 {
691  m_cipher.ProcessString(inString, length);
692  AttachedTransformation()->PutModifiable(inString, length);
693 }
694 
695 void 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 
852 HashFilter::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 
860 void HashFilter::IsolatedInitialize(const NameValuePairs &parameters)
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 
867 size_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 
898 void 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 
909 void 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 
920 void 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 
927 void 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 
964 byte * 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 
975 size_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 
986 void AuthenticatedEncryptionFilter::LastPut(const byte *inString, size_t length)
987 {
988  StreamTransformationFilter::LastPut(inString, length);
989  m_hf.MessageEnd();
990 }
991 
992 // *************************************************************
993 
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 
1007 void 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 
1019 byte * 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 
1030 size_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 
1045 void AuthenticatedDecryptionFilter::FirstPut(const byte *inString)
1046 {
1047  m_hashVerifier.Put(inString, m_firstSize);
1048 }
1049 
1050 void AuthenticatedDecryptionFilter::NextPutMultiple(const byte *inString, size_t length)
1051 {
1052  m_streamFilter.Put(inString, length);
1053 }
1054 
1055 void AuthenticatedDecryptionFilter::LastPut(const byte *inString, size_t length)
1056 {
1057  m_streamFilter.MessageEnd();
1058  m_hashVerifier.PutMessageEnd(inString, length);
1059 }
1060 
1061 // *************************************************************
1062 
1063 void SignerFilter::IsolatedInitialize(const NameValuePairs &parameters)
1064 {
1065  m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
1066  m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
1067 }
1068 
1069 size_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 
1094 void 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 
1106 void 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 
1127 void 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 
1134 void 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 
1159 size_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 
1169 bool Store::GetNextMessage()
1170 {
1171  if (!m_messageEnd && !AnyRetrievable())
1172  {
1173  m_messageEnd=true;
1174  return true;
1175  }
1176  else
1177  return false;
1178 }
1179 
1180 unsigned 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 
1193 void 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 
1203 size_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 
1212 size_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 
1222 void 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 
1230 size_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 
1242 size_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 
1256 size_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 
1264 NAMESPACE_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.
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.
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.
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.
byte * ChannelCreatePutSpace(const std::string &channel, size_t &size)
Request space which can be written into by the caller.
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.
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.
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
virtual byte * CreatePutSpace(size_t &size)
Request space which can be written into by the caller.
Definition: cryptlib.h:1725
Used to pass byte array input as part of a NameValuePairs object.
Definition: algparam.h:99
size_t size() const
Length of the memory block.
Definition: algparam.h:117
byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:113
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
size_t size() const
Length of the memory block.
Definition: algparam.h:88
const byte * begin() const
Pointer to the first byte in the memory block.
Definition: algparam.h:84
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.
BufferedTransformation * AttachedTransformation()
Retrieve attached transformation.
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.
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.
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.
byte * CreatePutSpace(size_t &size)
Request space which can be written into by the caller.
Definition: filters.h:598
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
virtual bool SignatureUpfront() const
Determines whether the signature must be input before the message.
Definition: cryptlib.h:2853
virtual size_t SignatureLength() const =0
Provides the signature length if it only depends on the key.
virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
Sign and delete the messageAccumulator.
virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0
Create a new HashTransformation to accumulate the message to be signed.
Interface for public-key signature verifiers.
Definition: cryptlib.h:2946
virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0
Check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0
Input signature into a message accumulator.
virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0
Create a new HashTransformation to accumulate the message to be verified.
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<byte> 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
#define SIZE_MAX
The maximum value of a machine word.
Definition: misc.h:120
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 T & STDMIN(const T &a, const T &b)
Replacement function for std::min.
Definition: misc.h:657
const T1 UnsignedMin(const T1 &a, const T2 &b)
Safe comparison of values that could be negative and incorrectly promoted.
Definition: misc.h:695
const T & STDMAX(const T &a, const T &b)
Replacement function for std::max.
Definition: misc.h:668
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 * TruncatedDigestSize()
int
Definition: argnames.h:51
const char * AuthenticatedDecryptionFilterFlags()
word32
Definition: argnames.h:54
const char * BlockPaddingScheme()
StreamTransformationFilter::BlockPaddingScheme.
Definition: argnames.h:52
const char * OutputBuffer()
ByteArrayParameter.
Definition: argnames.h:57
const char * HashVerificationFilterFlags()
word32
Definition: argnames.h:53
const char * PutMessage()
bool
Definition: argnames.h:50
const char * InputBuffer()
ConstByteArrayParameter.
Definition: argnames.h:56
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