Crypto++
filters.cpp
1 // filters.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #ifndef CRYPTOPP_IMPORTS
6 
7 #include "filters.h"
8 #include "mqueue.h"
9 #include "fltrimpl.h"
10 #include "argnames.h"
11 #include <memory>
12 #include <functional>
13 
14 NAMESPACE_BEGIN(CryptoPP)
15 
17  : m_attachment(attachment), m_continueAt(0)
18 {
19 }
20 
21 BufferedTransformation * Filter::NewDefaultAttachment() const
22 {
23  return new MessageQueue;
24 }
25 
27 {
28  if (m_attachment.get() == NULL)
29  m_attachment.reset(NewDefaultAttachment());
30  return m_attachment.get();
31 }
32 
34 {
35  if (m_attachment.get() == NULL)
36  const_cast<Filter *>(this)->m_attachment.reset(NewDefaultAttachment());
37  return m_attachment.get();
38 }
39 
41 {
42  m_attachment.reset(newOut);
43 }
44 
45 void Filter::Insert(Filter *filter)
46 {
47  filter->m_attachment.reset(m_attachment.release());
48  m_attachment.reset(filter);
49 }
50 
51 size_t Filter::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
52 {
53  return AttachedTransformation()->CopyRangeTo2(target, begin, end, channel, blocking);
54 }
55 
56 size_t Filter::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
57 {
58  return AttachedTransformation()->TransferTo2(target, transferBytes, channel, blocking);
59 }
60 
61 void Filter::Initialize(const NameValuePairs &parameters, int propagation)
62 {
63  m_continueAt = 0;
64  IsolatedInitialize(parameters);
65  PropagateInitialize(parameters, propagation);
66 }
67 
68 bool Filter::Flush(bool hardFlush, int propagation, bool blocking)
69 {
70  switch (m_continueAt)
71  {
72  case 0:
73  if (IsolatedFlush(hardFlush, blocking))
74  return true;
75  case 1:
76  if (OutputFlush(1, hardFlush, propagation, blocking))
77  return true;
78  }
79  return false;
80 }
81 
82 bool Filter::MessageSeriesEnd(int propagation, bool blocking)
83 {
84  switch (m_continueAt)
85  {
86  case 0:
87  if (IsolatedMessageSeriesEnd(blocking))
88  return true;
89  case 1:
90  if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
91  return true;
92  }
93  return false;
94 }
95 
96 void Filter::PropagateInitialize(const NameValuePairs &parameters, int propagation)
97 {
98  if (propagation)
99  AttachedTransformation()->Initialize(parameters, propagation-1);
100 }
101 
102 size_t Filter::OutputModifiable(int outputSite, byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel)
103 {
104  if (messageEnd)
105  messageEnd--;
106  size_t result = AttachedTransformation()->ChannelPutModifiable2(channel, inString, length, messageEnd, blocking);
107  m_continueAt = result ? outputSite : 0;
108  return result;
109 }
110 
111 size_t Filter::Output(int outputSite, const byte *inString, size_t length, int messageEnd, bool blocking, const std::string &channel)
112 {
113  if (messageEnd)
114  messageEnd--;
115  size_t result = AttachedTransformation()->ChannelPut2(channel, inString, length, messageEnd, blocking);
116  m_continueAt = result ? outputSite : 0;
117  return result;
118 }
119 
120 bool Filter::OutputFlush(int outputSite, bool hardFlush, int propagation, bool blocking, const std::string &channel)
121 {
122  if (propagation && AttachedTransformation()->ChannelFlush(channel, hardFlush, propagation-1, blocking))
123  {
124  m_continueAt = outputSite;
125  return true;
126  }
127  m_continueAt = 0;
128  return false;
129 }
130 
131 bool Filter::OutputMessageSeriesEnd(int outputSite, int propagation, bool blocking, const std::string &channel)
132 {
133  if (propagation && AttachedTransformation()->ChannelMessageSeriesEnd(channel, propagation-1, blocking))
134  {
135  m_continueAt = outputSite;
136  return true;
137  }
138  m_continueAt = 0;
139  return false;
140 }
141 
142 // *************************************************************
143 
144 void MeterFilter::ResetMeter()
145 {
146  m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0;
147  m_rangesToSkip.clear();
148 }
149 
150 void MeterFilter::AddRangeToSkip(unsigned int message, lword position, lword size, bool sortNow)
151 {
152  MessageRange r = {message, position, size};
153  m_rangesToSkip.push_back(r);
154  if (sortNow)
155  std::sort(m_rangesToSkip.begin(), m_rangesToSkip.end());
156 }
157 
158 size_t MeterFilter::PutMaybeModifiable(byte *begin, size_t length, int messageEnd, bool blocking, bool modifiable)
159 {
160  if (!m_transparent)
161  return 0;
162 
163  size_t t;
164  FILTER_BEGIN;
165 
166  m_begin = begin;
167  m_length = length;
168 
169  while (m_length > 0 || messageEnd)
170  {
171  if (m_length > 0 && !m_rangesToSkip.empty() && m_rangesToSkip.front().message == m_totalMessages && m_currentMessageBytes + m_length > m_rangesToSkip.front().position)
172  {
173  FILTER_OUTPUT_MAYBE_MODIFIABLE(1, m_begin, t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position, m_currentMessageBytes), false, modifiable);
174 
175  assert(t < m_length);
176  m_begin += t;
177  m_length -= t;
178  m_currentMessageBytes += t;
179  m_totalBytes += t;
180 
181  if (m_currentMessageBytes + m_length < m_rangesToSkip.front().position + m_rangesToSkip.front().size)
182  t = m_length;
183  else
184  {
185  t = (size_t)SaturatingSubtract(m_rangesToSkip.front().position + m_rangesToSkip.front().size, m_currentMessageBytes);
186  assert(t <= m_length);
187  m_rangesToSkip.pop_front();
188  }
189 
190  m_begin += t;
191  m_length -= t;
192  m_currentMessageBytes += t;
193  m_totalBytes += t;
194  }
195  else
196  {
197  FILTER_OUTPUT_MAYBE_MODIFIABLE(2, m_begin, m_length, messageEnd, modifiable);
198 
199  m_currentMessageBytes += m_length;
200  m_totalBytes += m_length;
201  m_length = 0;
202 
203  if (messageEnd)
204  {
205  m_currentMessageBytes = 0;
206  m_currentSeriesMessages++;
207  m_totalMessages++;
208  messageEnd = false;
209  }
210  }
211  }
212 
213  FILTER_END_NO_MESSAGE_END;
214 }
215 
216 size_t MeterFilter::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
217 {
218  return PutMaybeModifiable(const_cast<byte *>(begin), length, messageEnd, blocking, false);
219 }
220 
221 size_t MeterFilter::PutModifiable2(byte *begin, size_t length, int messageEnd, bool blocking)
222 {
223  return PutMaybeModifiable(begin, length, messageEnd, blocking, true);
224 }
225 
226 bool MeterFilter::IsolatedMessageSeriesEnd(bool blocking)
227 {
228  m_currentMessageBytes = 0;
229  m_currentSeriesMessages = 0;
230  m_totalMessageSeries++;
231  return false;
232 }
233 
234 // *************************************************************
235 
236 void FilterWithBufferedInput::BlockQueue::ResetQueue(size_t blockSize, size_t maxBlocks)
237 {
238  m_buffer.New(blockSize * maxBlocks);
239  m_blockSize = blockSize;
240  m_maxBlocks = maxBlocks;
241  m_size = 0;
242  m_begin = m_buffer;
243 }
244 
245 byte *FilterWithBufferedInput::BlockQueue::GetBlock()
246 {
247  if (m_size >= m_blockSize)
248  {
249  byte *ptr = m_begin;
250  if ((m_begin+=m_blockSize) == m_buffer.end())
251  m_begin = m_buffer;
252  m_size -= m_blockSize;
253  return ptr;
254  }
255  else
256  return NULL;
257 }
258 
259 byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBytes)
260 {
261  numberOfBytes = STDMIN(numberOfBytes, STDMIN(size_t(m_buffer.end()-m_begin), m_size));
262  byte *ptr = m_begin;
263  m_begin += numberOfBytes;
264  m_size -= numberOfBytes;
265  if (m_size == 0 || m_begin == m_buffer.end())
266  m_begin = m_buffer;
267  return ptr;
268 }
269 
270 size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
271 {
272  size_t size = m_size;
273  size_t numberOfBytes = m_maxBlocks*m_blockSize;
274  const byte *ptr = GetContigousBlocks(numberOfBytes);
275  memcpy(outString, ptr, numberOfBytes);
276  memcpy(outString+numberOfBytes, m_begin, m_size);
277  m_size = 0;
278  return size;
279 }
280 
281 void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length)
282 {
283  assert(m_size + length <= m_buffer.size());
284  byte *end = (m_size < size_t(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size();
285  size_t len = STDMIN(length, size_t(m_buffer.end()-end));
286  memcpy(end, inString, len);
287  if (len < length)
288  memcpy(m_buffer, inString+len, length-len);
289  m_size += length;
290 }
291 
292 FilterWithBufferedInput::FilterWithBufferedInput(BufferedTransformation *attachment)
293  : Filter(attachment)
294 {
295 }
296 
297 FilterWithBufferedInput::FilterWithBufferedInput(size_t firstSize, size_t blockSize, size_t lastSize, BufferedTransformation *attachment)
298  : Filter(attachment), m_firstSize(firstSize), m_blockSize(blockSize), m_lastSize(lastSize)
299  , m_firstInputDone(false)
300 {
301  if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
302  throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
303 
304  m_queue.ResetQueue(1, m_firstSize);
305 }
306 
307 void FilterWithBufferedInput::IsolatedInitialize(const NameValuePairs &parameters)
308 {
309  InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize);
310  if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
311  throw InvalidArgument("FilterWithBufferedInput: invalid buffer size");
312  m_queue.ResetQueue(1, m_firstSize);
313  m_firstInputDone = false;
314 }
315 
316 bool FilterWithBufferedInput::IsolatedFlush(bool hardFlush, bool blocking)
317 {
318  if (!blocking)
319  throw BlockingInputOnly("FilterWithBufferedInput");
320 
321  if (hardFlush)
322  ForceNextPut();
323  FlushDerived();
324 
325  return false;
326 }
327 
328 size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString, size_t length, int messageEnd, bool blocking, bool modifiable)
329 {
330  if (!blocking)
331  throw BlockingInputOnly("FilterWithBufferedInput");
332 
333  if (length != 0)
334  {
335  size_t newLength = m_queue.CurrentSize() + length;
336 
337  if (!m_firstInputDone && newLength >= m_firstSize)
338  {
339  size_t len = m_firstSize - m_queue.CurrentSize();
340  m_queue.Put(inString, len);
341  FirstPut(m_queue.GetContigousBlocks(m_firstSize));
342  assert(m_queue.CurrentSize() == 0);
343  m_queue.ResetQueue(m_blockSize, (2*m_blockSize+m_lastSize-2)/m_blockSize);
344 
345  inString += len;
346  newLength -= m_firstSize;
347  m_firstInputDone = true;
348  }
349 
350  if (m_firstInputDone)
351  {
352  if (m_blockSize == 1)
353  {
354  while (newLength > m_lastSize && m_queue.CurrentSize() > 0)
355  {
356  size_t len = newLength - m_lastSize;
357  byte *ptr = m_queue.GetContigousBlocks(len);
358  NextPutModifiable(ptr, len);
359  newLength -= len;
360  }
361 
362  if (newLength > m_lastSize)
363  {
364  size_t len = newLength - m_lastSize;
365  NextPutMaybeModifiable(inString, len, modifiable);
366  inString += len;
367  newLength -= len;
368  }
369  }
370  else
371  {
372  while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize)
373  {
374  NextPutModifiable(m_queue.GetBlock(), m_blockSize);
375  newLength -= m_blockSize;
376  }
377 
378  if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0)
379  {
380  assert(m_queue.CurrentSize() < m_blockSize);
381  size_t len = m_blockSize - m_queue.CurrentSize();
382  m_queue.Put(inString, len);
383  inString += len;
384  NextPutModifiable(m_queue.GetBlock(), m_blockSize);
385  newLength -= m_blockSize;
386  }
387 
388  if (newLength >= m_blockSize + m_lastSize)
389  {
390  size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize);
391  NextPutMaybeModifiable(inString, len, modifiable);
392  inString += len;
393  newLength -= len;
394  }
395  }
396  }
397 
398  m_queue.Put(inString, newLength - m_queue.CurrentSize());
399  }
400 
401  if (messageEnd)
402  {
403  if (!m_firstInputDone && m_firstSize==0)
404  FirstPut(NULL);
405 
406  SecByteBlock temp(m_queue.CurrentSize());
407  m_queue.GetAll(temp);
408  LastPut(temp, temp.size());
409 
410  m_firstInputDone = false;
411  m_queue.ResetQueue(1, m_firstSize);
412 
413  Output(1, NULL, 0, messageEnd, blocking);
414  }
415  return 0;
416 }
417 
419 {
420  if (!m_firstInputDone)
421  return;
422 
423  if (m_blockSize > 1)
424  {
425  while (m_queue.CurrentSize() >= m_blockSize)
426  NextPutModifiable(m_queue.GetBlock(), m_blockSize);
427  }
428  else
429  {
430  size_t len;
431  while ((len = m_queue.CurrentSize()) > 0)
432  NextPutModifiable(m_queue.GetContigousBlocks(len), len);
433  }
434 }
435 
436 void FilterWithBufferedInput::NextPutMultiple(const byte *inString, size_t length)
437 {
438  assert(m_blockSize > 1); // m_blockSize = 1 should always override this function
439  while (length > 0)
440  {
441  assert(length >= m_blockSize);
442  NextPutSingle(inString);
443  inString += m_blockSize;
444  length -= m_blockSize;
445  }
446 }
447 
448 // *************************************************************
449 
450 void Redirector::Initialize(const NameValuePairs &parameters, int propagation)
451 {
452  m_target = parameters.GetValueWithDefault("RedirectionTargetPointer", (BufferedTransformation*)NULL);
453  m_behavior = parameters.GetIntValueWithDefault("RedirectionBehavior", PASS_EVERYTHING);
454 
455  if (m_target && GetPassSignals())
456  m_target->Initialize(parameters, propagation);
457 }
458 
459 // *************************************************************
460 
461 ProxyFilter::ProxyFilter(BufferedTransformation *filter, size_t firstSize, size_t lastSize, BufferedTransformation *attachment)
462  : FilterWithBufferedInput(firstSize, 1, lastSize, attachment), m_filter(filter)
463 {
464  if (m_filter.get())
465  m_filter->Attach(new OutputProxy(*this, false));
466 }
467 
468 bool ProxyFilter::IsolatedFlush(bool hardFlush, bool blocking)
469 {
470  return m_filter.get() ? m_filter->Flush(hardFlush, -1, blocking) : false;
471 }
472 
473 void ProxyFilter::SetFilter(Filter *filter)
474 {
475  m_filter.reset(filter);
476  if (filter)
477  {
478  OutputProxy *proxy;
479  std::auto_ptr<OutputProxy> temp(proxy = new OutputProxy(*this, false));
480  m_filter->TransferAllTo(*proxy);
481  m_filter->Attach(temp.release());
482  }
483 }
484 
485 void ProxyFilter::NextPutMultiple(const byte *s, size_t len)
486 {
487  if (m_filter.get())
488  m_filter->Put(s, len);
489 }
490 
491 void ProxyFilter::NextPutModifiable(byte *s, size_t len)
492 {
493  if (m_filter.get())
494  m_filter->PutModifiable(s, len);
495 }
496 
497 // *************************************************************
498 
499 void RandomNumberSink::IsolatedInitialize(const NameValuePairs &parameters)
500 {
501  parameters.GetRequiredParameter("RandomNumberSink", "RandomNumberGeneratorPointer", m_rng);
502 }
503 
504 size_t RandomNumberSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
505 {
506  m_rng->IncorporateEntropy(begin, length);
507  return 0;
508 }
509 
510 size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
511 {
512  if (m_buf+m_total != begin)
513  memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
514  m_total += length;
515  return 0;
516 }
517 
518 byte * ArraySink::CreatePutSpace(size_t &size)
519 {
520  size = SaturatingSubtract(m_size, m_total);
521  return m_buf + m_total;
522 }
523 
524 void ArraySink::IsolatedInitialize(const NameValuePairs &parameters)
525 {
526  ByteArrayParameter array;
527  if (!parameters.GetValue(Name::OutputBuffer(), array))
528  throw InvalidArgument("ArraySink: missing OutputBuffer argument");
529  m_buf = array.begin();
530  m_size = array.size();
531  m_total = 0;
532 }
533 
534 size_t ArrayXorSink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
535 {
536  xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
537  m_total += length;
538  return 0;
539 }
540 
541 // *************************************************************
542 
543 StreamTransformationFilter::StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment, BlockPaddingScheme padding, bool allowAuthenticatedSymmetricCipher)
544  : FilterWithBufferedInput(attachment)
545  , m_cipher(c)
546 {
547  assert(c.MinLastBlockSize() == 0 || c.MinLastBlockSize() > c.MandatoryBlockSize());
548 
549  if (!allowAuthenticatedSymmetricCipher && dynamic_cast<AuthenticatedSymmetricCipher *>(&c) != 0)
550  throw InvalidArgument("StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher");
551 
552  IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding));
553 }
554 
555 size_t StreamTransformationFilter::LastBlockSize(StreamTransformation &c, BlockPaddingScheme padding)
556 {
557  if (c.MinLastBlockSize() > 0)
558  return c.MinLastBlockSize();
559  else if (c.MandatoryBlockSize() > 1 && !c.IsForwardTransformation() && padding != NO_PADDING && padding != ZEROS_PADDING)
560  return c.MandatoryBlockSize();
561  else
562  return 0;
563 }
564 
565 void StreamTransformationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
566 {
567  BlockPaddingScheme padding = parameters.GetValueWithDefault(Name::BlockPaddingScheme(), DEFAULT_PADDING);
568  bool isBlockCipher = (m_cipher.MandatoryBlockSize() > 1 && m_cipher.MinLastBlockSize() == 0);
569 
570  if (padding == DEFAULT_PADDING)
571  m_padding = isBlockCipher ? PKCS_PADDING : NO_PADDING;
572  else
573  m_padding = padding;
574 
575  if (!isBlockCipher && (m_padding == PKCS_PADDING || m_padding == ONE_AND_ZEROS_PADDING))
576  throw InvalidArgument("StreamTransformationFilter: PKCS_PADDING and ONE_AND_ZEROS_PADDING cannot be used with " + m_cipher.AlgorithmName());
577 
578  firstSize = 0;
579  blockSize = m_cipher.MandatoryBlockSize();
580  lastSize = LastBlockSize(m_cipher, m_padding);
581 }
582 
583 void StreamTransformationFilter::FirstPut(const byte *inString)
584 {
585  m_optimalBufferSize = m_cipher.OptimalBlockSize();
586  m_optimalBufferSize = (unsigned int)STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
587 }
588 
589 void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t length)
590 {
591  if (!length)
592  return;
593 
594  size_t s = m_cipher.MandatoryBlockSize();
595 
596  do
597  {
598  size_t len = m_optimalBufferSize;
599  byte *space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, length, len);
600  if (len < length)
601  {
602  if (len == m_optimalBufferSize)
603  len -= m_cipher.GetOptimalBlockSizeUsed();
604  len = RoundDownToMultipleOf(len, s);
605  }
606  else
607  len = length;
608  m_cipher.ProcessString(space, inString, len);
609  AttachedTransformation()->PutModifiable(space, len);
610  inString += len;
611  length -= len;
612  }
613  while (length > 0);
614 }
615 
616 void StreamTransformationFilter::NextPutModifiable(byte *inString, size_t length)
617 {
618  m_cipher.ProcessString(inString, length);
619  AttachedTransformation()->PutModifiable(inString, length);
620 }
621 
622 void StreamTransformationFilter::LastPut(const byte *inString, size_t length)
623 {
624  byte *space = NULL;
625 
626  switch (m_padding)
627  {
628  case NO_PADDING:
629  case ZEROS_PADDING:
630  if (length > 0)
631  {
632  size_t minLastBlockSize = m_cipher.MinLastBlockSize();
633  bool isForwardTransformation = m_cipher.IsForwardTransformation();
634 
635  if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize))
636  {
637  // do padding
638  size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_cipher.MandatoryBlockSize());
639  space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, blockSize);
640  memcpy(space, inString, length);
641  memset(space + length, 0, blockSize - length);
642  m_cipher.ProcessLastBlock(space, space, blockSize);
643  AttachedTransformation()->Put(space, blockSize);
644  }
645  else
646  {
647  if (minLastBlockSize == 0)
648  {
649  if (isForwardTransformation)
650  throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified");
651  else
652  throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
653  }
654 
655  space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, length, m_optimalBufferSize);
656  m_cipher.ProcessLastBlock(space, inString, length);
657  AttachedTransformation()->Put(space, length);
658  }
659  }
660  break;
661 
662  case PKCS_PADDING:
663  case ONE_AND_ZEROS_PADDING:
664  unsigned int s;
665  s = m_cipher.MandatoryBlockSize();
666  assert(s > 1);
667  space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, m_optimalBufferSize);
668  if (m_cipher.IsForwardTransformation())
669  {
670  assert(length < s);
671  memcpy(space, inString, length);
672  if (m_padding == PKCS_PADDING)
673  {
674  assert(s < 256);
675  byte pad = byte(s-length);
676  memset(space+length, pad, s-length);
677  }
678  else
679  {
680  space[length] = 0x80;
681  memset(space+length+1, 0, s-length-1);
682  }
683  m_cipher.ProcessData(space, space, s);
684  AttachedTransformation()->Put(space, s);
685  }
686  else
687  {
688  if (length != s)
689  throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size");
690  m_cipher.ProcessData(space, inString, s);
691  if (m_padding == PKCS_PADDING)
692  {
693  byte pad = space[s-1];
694  if (pad < 1 || pad > s || std::find_if(space+s-pad, space+s, std::bind2nd(std::not_equal_to<byte>(), pad)) != space+s)
695  throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found");
696  length = s-pad;
697  }
698  else
699  {
700  while (length > 1 && space[length-1] == 0)
701  --length;
702  if (space[--length] != 0x80)
703  throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found");
704  }
705  AttachedTransformation()->Put(space, length);
706  }
707  break;
708 
709  default:
710  assert(false);
711  }
712 }
713 
714 // *************************************************************
715 
716 HashFilter::HashFilter(HashTransformation &hm, BufferedTransformation *attachment, bool putMessage, int truncatedDigestSize, const std::string &messagePutChannel, const std::string &hashPutChannel)
717  : m_hashModule(hm), m_putMessage(putMessage), m_messagePutChannel(messagePutChannel), m_hashPutChannel(hashPutChannel)
718 {
719  m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize;
720  Detach(attachment);
721 }
722 
723 void HashFilter::IsolatedInitialize(const NameValuePairs &parameters)
724 {
725  m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
726  int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1);
727  m_digestSize = s < 0 ? m_hashModule.DigestSize() : s;
728 }
729 
730 size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
731 {
732  FILTER_BEGIN;
733  if (m_putMessage)
734  FILTER_OUTPUT3(1, 0, inString, length, 0, m_messagePutChannel);
735  m_hashModule.Update(inString, length);
736  if (messageEnd)
737  {
738  {
739  size_t size;
740  m_space = HelpCreatePutSpace(*AttachedTransformation(), m_hashPutChannel, m_digestSize, m_digestSize, size = m_digestSize);
741  m_hashModule.TruncatedFinal(m_space, m_digestSize);
742  }
743  FILTER_OUTPUT3(2, 0, m_space, m_digestSize, messageEnd, m_hashPutChannel);
744  }
745  FILTER_END_NO_MESSAGE_END;
746 }
747 
748 // *************************************************************
749 
750 HashVerificationFilter::HashVerificationFilter(HashTransformation &hm, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize)
751  : FilterWithBufferedInput(attachment)
752  , m_hashModule(hm)
753 {
754  IsolatedInitialize(MakeParameters(Name::HashVerificationFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize));
755 }
756 
757 void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
758 {
759  m_flags = parameters.GetValueWithDefault(Name::HashVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
760  int s = parameters.GetIntValueWithDefault(Name::TruncatedDigestSize(), -1);
761  m_digestSize = s < 0 ? m_hashModule.DigestSize() : s;
762  m_verified = false;
763  firstSize = m_flags & HASH_AT_BEGIN ? m_digestSize : 0;
764  blockSize = 1;
765  lastSize = m_flags & HASH_AT_BEGIN ? 0 : m_digestSize;
766 }
767 
768 void HashVerificationFilter::FirstPut(const byte *inString)
769 {
770  if (m_flags & HASH_AT_BEGIN)
771  {
772  m_expectedHash.New(m_digestSize);
773  memcpy(m_expectedHash, inString, m_expectedHash.size());
774  if (m_flags & PUT_HASH)
775  AttachedTransformation()->Put(inString, m_expectedHash.size());
776  }
777 }
778 
779 void HashVerificationFilter::NextPutMultiple(const byte *inString, size_t length)
780 {
781  m_hashModule.Update(inString, length);
782  if (m_flags & PUT_MESSAGE)
783  AttachedTransformation()->Put(inString, length);
784 }
785 
786 void HashVerificationFilter::LastPut(const byte *inString, size_t length)
787 {
788  if (m_flags & HASH_AT_BEGIN)
789  {
790  assert(length == 0);
791  m_verified = m_hashModule.TruncatedVerify(m_expectedHash, m_digestSize);
792  }
793  else
794  {
795  m_verified = (length==m_digestSize && m_hashModule.TruncatedVerify(inString, length));
796  if (m_flags & PUT_HASH)
797  AttachedTransformation()->Put(inString, length);
798  }
799 
800  if (m_flags & PUT_RESULT)
801  AttachedTransformation()->Put(m_verified);
802 
803  if ((m_flags & THROW_EXCEPTION) && !m_verified)
804  throw HashVerificationFailed();
805 }
806 
807 // *************************************************************
808 
810  bool putAAD, int truncatedDigestSize, const std::string &macChannel, BlockPaddingScheme padding)
811  : StreamTransformationFilter(c, attachment, padding, true)
812  , m_hf(c, new OutputProxy(*this, false), putAAD, truncatedDigestSize, AAD_CHANNEL, macChannel)
813 {
814  assert(c.IsForwardTransformation());
815 }
816 
817 void AuthenticatedEncryptionFilter::IsolatedInitialize(const NameValuePairs &parameters)
818 {
819  m_hf.IsolatedInitialize(parameters);
820  StreamTransformationFilter::IsolatedInitialize(parameters);
821 }
822 
823 byte * AuthenticatedEncryptionFilter::ChannelCreatePutSpace(const std::string &channel, size_t &size)
824 {
825  if (channel.empty())
827 
828  if (channel == AAD_CHANNEL)
829  return m_hf.CreatePutSpace(size);
830 
831  throw InvalidChannelName("AuthenticatedEncryptionFilter", channel);
832 }
833 
834 size_t AuthenticatedEncryptionFilter::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
835 {
836  if (channel.empty())
837  return StreamTransformationFilter::Put2(begin, length, messageEnd, blocking);
838 
839  if (channel == AAD_CHANNEL)
840  return m_hf.Put2(begin, length, 0, blocking);
841 
842  throw InvalidChannelName("AuthenticatedEncryptionFilter", channel);
843 }
844 
845 void AuthenticatedEncryptionFilter::LastPut(const byte *inString, size_t length)
846 {
847  StreamTransformationFilter::LastPut(inString, length);
848  m_hf.MessageEnd();
849 }
850 
851 // *************************************************************
852 
853 AuthenticatedDecryptionFilter::AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment, word32 flags, int truncatedDigestSize, BlockPaddingScheme padding)
854  : FilterWithBufferedInput(attachment)
855  , m_hashVerifier(c, new OutputProxy(*this, false))
856  , m_streamFilter(c, new OutputProxy(*this, false), padding, true)
857 {
858  assert(!c.IsForwardTransformation() || c.IsSelfInverting());
859  IsolatedInitialize(MakeParameters(Name::BlockPaddingScheme(), padding)(Name::AuthenticatedDecryptionFilterFlags(), flags)(Name::TruncatedDigestSize(), truncatedDigestSize));
860 }
861 
862 void AuthenticatedDecryptionFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
863 {
864  word32 flags = parameters.GetValueWithDefault(Name::AuthenticatedDecryptionFilterFlags(), (word32)DEFAULT_FLAGS);
865 
866  m_hashVerifier.Initialize(CombinedNameValuePairs(parameters, MakeParameters(Name::HashVerificationFilterFlags(), flags)));
867  m_streamFilter.Initialize(parameters);
868 
869  firstSize = m_hashVerifier.m_firstSize;
870  blockSize = 1;
871  lastSize = m_hashVerifier.m_lastSize;
872 }
873 
874 byte * AuthenticatedDecryptionFilter::ChannelCreatePutSpace(const std::string &channel, size_t &size)
875 {
876  if (channel.empty())
877  return m_streamFilter.CreatePutSpace(size);
878 
879  if (channel == AAD_CHANNEL)
880  return m_hashVerifier.CreatePutSpace(size);
881 
882  throw InvalidChannelName("AuthenticatedDecryptionFilter", channel);
883 }
884 
885 size_t AuthenticatedDecryptionFilter::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
886 {
887  if (channel.empty())
888  {
889  if (m_lastSize > 0)
890  m_hashVerifier.ForceNextPut();
891  return FilterWithBufferedInput::Put2(begin, length, messageEnd, blocking);
892  }
893 
894  if (channel == AAD_CHANNEL)
895  return m_hashVerifier.Put2(begin, length, 0, blocking);
896 
897  throw InvalidChannelName("AuthenticatedDecryptionFilter", channel);
898 }
899 
900 void AuthenticatedDecryptionFilter::FirstPut(const byte *inString)
901 {
902  m_hashVerifier.Put(inString, m_firstSize);
903 }
904 
905 void AuthenticatedDecryptionFilter::NextPutMultiple(const byte *inString, size_t length)
906 {
907  m_streamFilter.Put(inString, length);
908 }
909 
910 void AuthenticatedDecryptionFilter::LastPut(const byte *inString, size_t length)
911 {
912  m_streamFilter.MessageEnd();
913  m_hashVerifier.PutMessageEnd(inString, length);
914 }
915 
916 // *************************************************************
917 
918 void SignerFilter::IsolatedInitialize(const NameValuePairs &parameters)
919 {
920  m_putMessage = parameters.GetValueWithDefault(Name::PutMessage(), false);
921  m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
922 }
923 
924 size_t SignerFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
925 {
926  FILTER_BEGIN;
927  m_messageAccumulator->Update(inString, length);
928  if (m_putMessage)
929  FILTER_OUTPUT(1, inString, length, 0);
930  if (messageEnd)
931  {
932  m_buf.New(m_signer.SignatureLength());
933  m_signer.Sign(m_rng, m_messageAccumulator.release(), m_buf);
934  FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd);
935  m_messageAccumulator.reset(m_signer.NewSignatureAccumulator(m_rng));
936  }
937  FILTER_END_NO_MESSAGE_END;
938 }
939 
940 SignatureVerificationFilter::SignatureVerificationFilter(const PK_Verifier &verifier, BufferedTransformation *attachment, word32 flags)
941  : FilterWithBufferedInput(attachment)
942  , m_verifier(verifier)
943 {
944  IsolatedInitialize(MakeParameters(Name::SignatureVerificationFilterFlags(), flags));
945 }
946 
947 void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(const NameValuePairs &parameters, size_t &firstSize, size_t &blockSize, size_t &lastSize)
948 {
949  m_flags = parameters.GetValueWithDefault(Name::SignatureVerificationFilterFlags(), (word32)DEFAULT_FLAGS);
950  m_messageAccumulator.reset(m_verifier.NewVerificationAccumulator());
951  size_t size = m_verifier.SignatureLength();
952  assert(size != 0); // TODO: handle recoverable signature scheme
953  m_verified = false;
954  firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0;
955  blockSize = 1;
956  lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size;
957 }
958 
959 void SignatureVerificationFilter::FirstPut(const byte *inString)
960 {
961  if (m_flags & SIGNATURE_AT_BEGIN)
962  {
963  if (m_verifier.SignatureUpfront())
964  m_verifier.InputSignature(*m_messageAccumulator, inString, m_verifier.SignatureLength());
965  else
966  {
967  m_signature.New(m_verifier.SignatureLength());
968  memcpy(m_signature, inString, m_signature.size());
969  }
970 
971  if (m_flags & PUT_SIGNATURE)
972  AttachedTransformation()->Put(inString, m_signature.size());
973  }
974  else
975  {
976  assert(!m_verifier.SignatureUpfront());
977  }
978 }
979 
980 void SignatureVerificationFilter::NextPutMultiple(const byte *inString, size_t length)
981 {
982  m_messageAccumulator->Update(inString, length);
983  if (m_flags & PUT_MESSAGE)
984  AttachedTransformation()->Put(inString, length);
985 }
986 
987 void SignatureVerificationFilter::LastPut(const byte *inString, size_t length)
988 {
989  if (m_flags & SIGNATURE_AT_BEGIN)
990  {
991  assert(length == 0);
992  m_verifier.InputSignature(*m_messageAccumulator, m_signature, m_signature.size());
993  m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator);
994  }
995  else
996  {
997  m_verifier.InputSignature(*m_messageAccumulator, inString, length);
998  m_verified = m_verifier.VerifyAndRestart(*m_messageAccumulator);
999  if (m_flags & PUT_SIGNATURE)
1000  AttachedTransformation()->Put(inString, length);
1001  }
1002 
1003  if (m_flags & PUT_RESULT)
1004  AttachedTransformation()->Put(m_verified);
1005 
1006  if ((m_flags & THROW_EXCEPTION) && !m_verified)
1007  throw SignatureVerificationFailed();
1008 }
1009 
1010 // *************************************************************
1011 
1012 size_t Source::PumpAll2(bool blocking)
1013 {
1014  unsigned int messageCount = UINT_MAX;
1015  do {
1016  RETURN_IF_NONZERO(PumpMessages2(messageCount, blocking));
1017  } while(messageCount == UINT_MAX);
1018 
1019  return 0;
1020 }
1021 
1023 {
1024  if (!m_messageEnd && !AnyRetrievable())
1025  {
1026  m_messageEnd=true;
1027  return true;
1028  }
1029  else
1030  return false;
1031 }
1032 
1033 unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
1034 {
1035  if (m_messageEnd || count == 0)
1036  return 0;
1037  else
1038  {
1039  CopyTo(target, ULONG_MAX, channel);
1040  if (GetAutoSignalPropagation())
1041  target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
1042  return 1;
1043  }
1044 }
1045 
1046 void StringStore::StoreInitialize(const NameValuePairs &parameters)
1047 {
1049  if (!parameters.GetValue(Name::InputBuffer(), array))
1050  throw InvalidArgument("StringStore: missing InputBuffer argument");
1051  m_store = array.begin();
1052  m_length = array.size();
1053  m_count = 0;
1054 }
1055 
1056 size_t StringStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
1057 {
1058  lword position = 0;
1059  size_t blockedBytes = CopyRangeTo2(target, position, transferBytes, channel, blocking);
1060  m_count += (size_t)position;
1061  transferBytes = position;
1062  return blockedBytes;
1063 }
1064 
1065 size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
1066 {
1067  size_t i = UnsignedMin(m_length, m_count+begin);
1068  size_t len = UnsignedMin(m_length-i, end-begin);
1069  size_t blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking);
1070  if (!blockedBytes)
1071  begin += len;
1072  return blockedBytes;
1073 }
1074 
1075 void RandomNumberStore::StoreInitialize(const NameValuePairs &parameters)
1076 {
1077  parameters.GetRequiredParameter("RandomNumberStore", "RandomNumberGeneratorPointer", m_rng);
1078  int length;
1079  parameters.GetRequiredIntParameter("RandomNumberStore", "RandomNumberStoreSize", length);
1080  m_length = length;
1081 }
1082 
1083 size_t RandomNumberStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
1084 {
1085  if (!blocking)
1086  throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object");
1087 
1088  transferBytes = UnsignedMin(transferBytes, m_length - m_count);
1089  m_rng->GenerateIntoBufferedTransformation(target, channel, transferBytes);
1090  m_count += transferBytes;
1091 
1092  return 0;
1093 }
1094 
1095 size_t NullStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const
1096 {
1097  static const byte nullBytes[128] = {0};
1098  while (begin < end)
1099  {
1100  size_t len = (size_t)STDMIN(end-begin, lword(128));
1101  size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
1102  if (blockedBytes)
1103  return blockedBytes;
1104  begin += len;
1105  }
1106  return 0;
1107 }
1108 
1109 size_t NullStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking)
1110 {
1111  lword begin = 0;
1112  size_t blockedBytes = NullStore::CopyRangeTo2(target, begin, transferBytes, channel, blocking);
1113  transferBytes = begin;
1114  m_size -= begin;
1115  return blockedBytes;
1116 }
1117 
1118 NAMESPACE_END
1119 
1120 #endif
virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length)
for ciphers where the last block of data is special, encrypt or decrypt the last block of data ...
Definition: cryptlib.cpp:194
used to pass byte array input as part of a NameValuePairs object
Definition: algparam.h:13
exception thrown when an invalid argument is detected
Definition: cryptlib.h:145
virtual bool AnyRetrievable() const
returns whether any bytes are currently ready for retrieval
Definition: cryptlib.cpp:394
virtual void ProcessData(byte *outString, const byte *inString, size_t length)=0
encrypt or decrypt an array of bytes of specified length
interface for for one direction (encryption or decryption) of a stream cipher or block cipher mode wi...
Definition: cryptlib.h:627
T GetValueWithDefault(const char *name, T defaultValue) const
get a named value, returns the default if the name doesn't exist
Definition: cryptlib.h:269
Message Queue.
Definition: mqueue.h:11
const char * HashVerificationFilterFlags()
word32
Definition: argnames.h:47
virtual void TruncatedFinal(byte *digest, size_t digestSize)=0
truncated version of Final()
const char * AuthenticatedDecryptionFilterFlags()
word32
Definition: argnames.h:48
const char * SignatureVerificationFilterFlags()
word32
Definition: argnames.h:49
const char * BlockPaddingScheme()
StreamTransformationFilter::BlockPaddingScheme.
Definition: argnames.h:46
bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
mark end of a series of messages
Definition: filters.cpp:82
a block of memory allocated using A
Definition: secblock.h:238
AuthenticatedDecryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment=NULL, word32 flags=DEFAULT_FLAGS, int truncatedDigestSize=-1, BlockPaddingScheme padding=DEFAULT_PADDING)
Definition: filters.cpp:853
StreamTransformationFilter(StreamTransformation &c, BufferedTransformation *attachment=NULL, BlockPaddingScheme padding=DEFAULT_PADDING, bool allowAuthenticatedSymmetricCipher=false)
Definition: filters.cpp:543
virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)=0
upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
void ProcessString(byte *inoutString, size_t length)
same as ProcessData(inoutString, inoutString, length)
Definition: cryptlib.h:499
bool GetNextMessage()
start retrieving the next message
Definition: filters.cpp:1022
void New(size_type newSize)
change size, without preserving contents
Definition: secblock.h:361
virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0
check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
virtual bool TruncatedVerify(const byte *digest, size_t digestLength)
truncated version of Verify()
Definition: cryptlib.cpp:301
virtual size_t SignatureLength() const =0
signature length if it only depends on the key, otherwise 0
interface for buffered transformations
Definition: cryptlib.h:771
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: filters.cpp:216
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: filters.cpp:924
virtual unsigned int GetOptimalBlockSizeUsed() const
returns how much of the current block is used up
Definition: cryptlib.h:483
size_t PutModifiable(byte *inString, size_t length, bool blocking=true)
input multiple bytes that may be modified by callee
Definition: cryptlib.h:804
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block
Definition: filters.cpp:51
bool GetValue(const char *name, T &value) const
get a named value, returns true if the name exists
Definition: cryptlib.h:262
virtual void Attach(BufferedTransformation *newAttachment)
add newAttachment to the end of attachment chain
Definition: cryptlib.cpp:650
int GetIntValueWithDefault(const char *name, int defaultValue) const
get a named value with type int, with default
Definition: cryptlib.h:286
exception thrown by a class if a non-implemented method is called
Definition: cryptlib.h:166
size_t Put(byte inByte, bool blocking=true)
input a byte for processing
Definition: cryptlib.h:785
virtual bool IsForwardTransformation() const =0
returns whether this is an encryption object
virtual unsigned int OptimalBlockSize() const
returns the input block size that is most efficient for this cipher
Definition: cryptlib.h:481
void Detach(BufferedTransformation *newAttachment=NULL)
delete the current attachment chain and replace it with newAttachment
Definition: filters.cpp:40
const std::string DEFAULT_CHANNEL
the default channel for BufferedTransformation, equal to the empty string
Definition: cryptlib.cpp:29
virtual bool IsSelfInverting() const =0
returns whether this transformation is self-inverting (e.g. xor with a keystream) ...
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block
Definition: filters.cpp:1095
virtual unsigned int MandatoryBlockSize() const
returns block size, if input must be processed in blocks, otherwise 1
Definition: cryptlib.h:477
virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
flush buffered input and/or output
Definition: cryptlib.cpp:334
BufferedTransformation * AttachedTransformation()
returns the object immediately attached to this object or NULL for no attachment
Definition: filters.cpp:26
const char * PutMessage()
bool
Definition: argnames.h:44
size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
input multiple bytes that may be modified by callee for blocking or non-blocking processing ...
Definition: filters.cpp:221
byte * CreatePutSpace(size_t &size)
request space which can be written into by the caller, and then used as input to Put() ...
Definition: filters.cpp:518
const char * InputBuffer()
ConstByteArrayParameter.
Definition: argnames.h:50
virtual std::string AlgorithmName() const
returns name of this algorithm, not universally implemented yet
Definition: cryptlib.h:343
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
Definition: filters.cpp:1109
virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
sign and delete messageAccumulator (even in case of exception thrown)
Definition: cryptlib.cpp:756
interface for the data processing part of stream ciphers
Definition: cryptlib.h:470
virtual size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const =0
upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: filters.cpp:510
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: filters.cpp:534
virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0
create a new HashTransformation to accumulate the message to be verified
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: filters.cpp:504
exception thrown by decryption filters when trying to decrypt an invalid ciphertext ...
Definition: cryptlib.h:159
const char * OutputBuffer()
ByteArrayParameter.
Definition: argnames.h:51
thrown by objects that have not implemented nonblocking input processing
Definition: cryptlib.h:821
Filter Wrapper for StreamTransformation, optionally handling padding/unpadding when needed...
Definition: filters.h:262
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
Definition: filters.cpp:56
byte * CreatePutSpace(size_t &size)
request space which can be written into by the caller, and then used as input to Put() ...
Definition: filters.h:299
interface for public-key signature verifiers
Definition: cryptlib.h:1388
virtual unsigned int DigestSize() const =0
size of the hash/digest/MAC returned by Final()
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
Definition: filters.cpp:1083
virtual bool SignatureUpfront() const
if this function returns true, during verification you must input the signature before the message...
Definition: cryptlib.h:1324
interface for hash functions and data processing part of MACs
Definition: cryptlib.h:531
size_t CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true) const
upon return, begin contains the start position of data yet to be finished copying, and returns the number of bytes left in the current transfer block
Definition: filters.cpp:1065
virtual byte * CreatePutSpace(size_t &size)
request space which can be written into by the caller, and then used as input to Put() ...
Definition: cryptlib.h:799
bool IsolatedFlush(bool hardFlush, bool blocking)
Definition: filters.cpp:468
const char * TruncatedDigestSize()
int
Definition: argnames.h:45
provides an implementation of BufferedTransformation's attachment interface
Definition: filters.h:17
size_t Put2(const byte *begin, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: filters.cpp:730
virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0
create a new HashTransformation to accumulate the message to be signed
void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
initialize or reinitialize this object
Definition: filters.cpp:61
void Initialize(const NameValuePairs &parameters, int propagation)
initialize or reinitialize this object
Definition: filters.cpp:450
size_t TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
Definition: filters.cpp:1056
lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
copy copyMax bytes of the buffered output to target as input
Definition: cryptlib.h:907
AuthenticatedEncryptionFilter(AuthenticatedSymmetricCipher &c, BufferedTransformation *attachment=NULL, bool putAAD=false, int truncatedDigestSize=-1, const std::string &macChannel=DEFAULT_CHANNEL, BlockPaddingScheme padding=DEFAULT_PADDING)
Definition: filters.cpp:809
virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0
input signature into a message accumulator
const std::string AAD_CHANNEL
channel for additional authenticated data, equal to "AAD"
Definition: cryptlib.cpp:30
bool IsolatedFlush(bool hardFlush, bool blocking)
Definition: filters.cpp:316
virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
initialize or reinitialize this object
Definition: cryptlib.cpp:328
exception thrown when input data is received that doesn't conform to expected format ...
Definition: cryptlib.h:152
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: filters.h:155
bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
flush buffered input and/or output
Definition: filters.cpp:68
virtual void Update(const byte *input, size_t length)=0
process more input
virtual unsigned int MinLastBlockSize() const
returns the minimum size of the last block, 0 indicating the last block is not special ...
Definition: cryptlib.h:496
virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
generate random bytes as input to a BufferedTransformation
Definition: cryptlib.cpp:275
virtual void IncorporateEntropy(const byte *input, size_t length)
update RNG state with additional unpredictable values
Definition: cryptlib.h:673
interface for retrieving values given their names
Definition: cryptlib.h:225