5 #ifndef CRYPTOPP_IMPORTS
14 NAMESPACE_BEGIN(CryptoPP)
17 : m_attachment(attachment), m_continueAt(0)
28 if (m_attachment.get() == NULL)
29 m_attachment.reset(NewDefaultAttachment());
30 return m_attachment.get();
35 if (m_attachment.get() == NULL)
36 const_cast<Filter *>(
this)->m_attachment.reset(NewDefaultAttachment());
37 return m_attachment.get();
42 m_attachment.reset(newOut);
45 void Filter::Insert(
Filter *filter)
47 filter->m_attachment.reset(m_attachment.release());
48 m_attachment.reset(filter);
64 IsolatedInitialize(parameters);
65 PropagateInitialize(parameters, propagation);
73 if (IsolatedFlush(hardFlush, blocking))
76 if (OutputFlush(1, hardFlush, propagation, blocking))
87 if (IsolatedMessageSeriesEnd(blocking))
90 if (ShouldPropagateMessageSeriesEnd() && OutputMessageSeriesEnd(1, propagation, blocking))
96 void Filter::PropagateInitialize(
const NameValuePairs ¶meters,
int propagation)
102 size_t Filter::OutputModifiable(
int outputSite, byte *inString,
size_t length,
int messageEnd,
bool blocking,
const std::string &channel)
106 size_t result =
AttachedTransformation()->ChannelPutModifiable2(channel, inString, length, messageEnd, blocking);
107 m_continueAt = result ? outputSite : 0;
111 size_t Filter::Output(
int outputSite,
const byte *inString,
size_t length,
int messageEnd,
bool blocking,
const std::string &channel)
116 m_continueAt = result ? outputSite : 0;
120 bool Filter::OutputFlush(
int outputSite,
bool hardFlush,
int propagation,
bool blocking,
const std::string &channel)
124 m_continueAt = outputSite;
131 bool Filter::OutputMessageSeriesEnd(
int outputSite,
int propagation,
bool blocking,
const std::string &channel)
135 m_continueAt = outputSite;
144 void MeterFilter::ResetMeter()
146 m_currentMessageBytes = m_totalBytes = m_currentSeriesMessages = m_totalMessages = m_totalMessageSeries = 0;
147 m_rangesToSkip.clear();
150 void MeterFilter::AddRangeToSkip(
unsigned int message, lword position, lword size,
bool sortNow)
152 MessageRange r = {message, position, size};
153 m_rangesToSkip.push_back(r);
155 std::sort(m_rangesToSkip.begin(), m_rangesToSkip.end());
158 size_t MeterFilter::PutMaybeModifiable(byte *begin,
size_t length,
int messageEnd,
bool blocking,
bool modifiable)
169 while (m_length > 0 || messageEnd)
171 if (m_length > 0 && !m_rangesToSkip.empty() && m_rangesToSkip.front().message == m_totalMessages && m_currentMessageBytes + m_length > m_rangesToSkip.front().position)
173 FILTER_OUTPUT_MAYBE_MODIFIABLE(1, m_begin, t = (
size_t)SaturatingSubtract(m_rangesToSkip.front().position, m_currentMessageBytes),
false, modifiable);
175 assert(t < m_length);
178 m_currentMessageBytes += t;
181 if (m_currentMessageBytes + m_length < m_rangesToSkip.front().position + m_rangesToSkip.front().size)
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();
192 m_currentMessageBytes += t;
197 FILTER_OUTPUT_MAYBE_MODIFIABLE(2, m_begin, m_length, messageEnd, modifiable);
199 m_currentMessageBytes += m_length;
200 m_totalBytes += m_length;
205 m_currentMessageBytes = 0;
206 m_currentSeriesMessages++;
213 FILTER_END_NO_MESSAGE_END;
218 return PutMaybeModifiable(const_cast<byte *>(begin), length, messageEnd, blocking,
false);
223 return PutMaybeModifiable(begin, length, messageEnd, blocking,
true);
226 bool MeterFilter::IsolatedMessageSeriesEnd(
bool blocking)
228 m_currentMessageBytes = 0;
229 m_currentSeriesMessages = 0;
230 m_totalMessageSeries++;
236 void FilterWithBufferedInput::BlockQueue::ResetQueue(
size_t blockSize,
size_t maxBlocks)
238 m_buffer.
New(blockSize * maxBlocks);
239 m_blockSize = blockSize;
240 m_maxBlocks = maxBlocks;
245 byte *FilterWithBufferedInput::BlockQueue::GetBlock()
247 if (m_size >= m_blockSize)
250 if ((m_begin+=m_blockSize) == m_buffer.end())
252 m_size -= m_blockSize;
259 byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(
size_t &numberOfBytes)
261 numberOfBytes = STDMIN(numberOfBytes, STDMIN(
size_t(m_buffer.end()-m_begin), m_size));
263 m_begin += numberOfBytes;
264 m_size -= numberOfBytes;
265 if (m_size == 0 || m_begin == m_buffer.end())
270 size_t FilterWithBufferedInput::BlockQueue::GetAll(byte *outString)
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);
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);
288 memcpy(m_buffer, inString+len, length-len);
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)
301 if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
304 m_queue.ResetQueue(1, m_firstSize);
307 void FilterWithBufferedInput::IsolatedInitialize(
const NameValuePairs ¶meters)
309 InitializeDerivedAndReturnNewSizes(parameters, m_firstSize, m_blockSize, m_lastSize);
310 if (m_firstSize < 0 || m_blockSize < 1 || m_lastSize < 0)
312 m_queue.ResetQueue(1, m_firstSize);
313 m_firstInputDone =
false;
328 size_t FilterWithBufferedInput::PutMaybeModifiable(byte *inString,
size_t length,
int messageEnd,
bool blocking,
bool modifiable)
331 throw BlockingInputOnly(
"FilterWithBufferedInput");
335 size_t newLength = m_queue.CurrentSize() + length;
337 if (!m_firstInputDone && newLength >= m_firstSize)
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);
346 newLength -= m_firstSize;
347 m_firstInputDone =
true;
350 if (m_firstInputDone)
352 if (m_blockSize == 1)
354 while (newLength > m_lastSize && m_queue.CurrentSize() > 0)
356 size_t len = newLength - m_lastSize;
357 byte *ptr = m_queue.GetContigousBlocks(len);
358 NextPutModifiable(ptr, len);
362 if (newLength > m_lastSize)
364 size_t len = newLength - m_lastSize;
365 NextPutMaybeModifiable(inString, len, modifiable);
372 while (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() >= m_blockSize)
374 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
375 newLength -= m_blockSize;
378 if (newLength >= m_blockSize + m_lastSize && m_queue.CurrentSize() > 0)
380 assert(m_queue.CurrentSize() < m_blockSize);
381 size_t len = m_blockSize - m_queue.CurrentSize();
382 m_queue.Put(inString, len);
384 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
385 newLength -= m_blockSize;
388 if (newLength >= m_blockSize + m_lastSize)
390 size_t len = RoundDownToMultipleOf(newLength - m_lastSize, m_blockSize);
391 NextPutMaybeModifiable(inString, len, modifiable);
398 m_queue.Put(inString, newLength - m_queue.CurrentSize());
403 if (!m_firstInputDone && m_firstSize==0)
407 m_queue.GetAll(temp);
408 LastPut(temp, temp.size());
410 m_firstInputDone =
false;
411 m_queue.ResetQueue(1, m_firstSize);
413 Output(1, NULL, 0, messageEnd, blocking);
420 if (!m_firstInputDone)
425 while (m_queue.CurrentSize() >= m_blockSize)
426 NextPutModifiable(m_queue.GetBlock(), m_blockSize);
431 while ((len = m_queue.CurrentSize()) > 0)
432 NextPutModifiable(m_queue.GetContigousBlocks(len), len);
436 void FilterWithBufferedInput::NextPutMultiple(
const byte *inString,
size_t length)
438 assert(m_blockSize > 1);
441 assert(length >= m_blockSize);
442 NextPutSingle(inString);
443 inString += m_blockSize;
444 length -= m_blockSize;
455 if (m_target && GetPassSignals())
456 m_target->
Initialize(parameters, propagation);
470 return m_filter.get() ? m_filter->
Flush(hardFlush, -1, blocking) :
false;
473 void ProxyFilter::SetFilter(
Filter *filter)
475 m_filter.reset(filter);
479 std::auto_ptr<OutputProxy> temp(proxy =
new OutputProxy(*
this,
false));
480 m_filter->TransferAllTo(*proxy);
481 m_filter->
Attach(temp.release());
485 void ProxyFilter::NextPutMultiple(
const byte *s,
size_t len)
488 m_filter->
Put(s, len);
491 void ProxyFilter::NextPutModifiable(byte *s,
size_t len)
499 void RandomNumberSink::IsolatedInitialize(
const NameValuePairs ¶meters)
501 parameters.GetRequiredParameter(
"RandomNumberSink",
"RandomNumberGeneratorPointer", m_rng);
510 size_t ArraySink::Put2(
const byte *begin,
size_t length,
int messageEnd,
bool blocking)
512 if (m_buf+m_total != begin)
513 memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
520 size = SaturatingSubtract(m_size, m_total);
521 return m_buf + m_total;
524 void ArraySink::IsolatedInitialize(
const NameValuePairs ¶meters)
529 m_buf = array.begin();
530 m_size = array.size();
536 xorbuf(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total)));
549 if (!allowAuthenticatedSymmetricCipher && dynamic_cast<AuthenticatedSymmetricCipher *>(&c) != 0)
550 throw InvalidArgument(
"StreamTransformationFilter: please use AuthenticatedEncryptionFilter and AuthenticatedDecryptionFilter for AuthenticatedSymmetricCipher");
555 size_t StreamTransformationFilter::LastBlockSize(
StreamTransformation &c, BlockPaddingScheme padding)
565 void StreamTransformationFilter::InitializeDerivedAndReturnNewSizes(
const NameValuePairs ¶meters,
size_t &firstSize,
size_t &blockSize,
size_t &lastSize)
570 if (padding == DEFAULT_PADDING)
571 m_padding = isBlockCipher ? PKCS_PADDING : NO_PADDING;
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());
580 lastSize = LastBlockSize(m_cipher, m_padding);
583 void StreamTransformationFilter::FirstPut(
const byte *inString)
586 m_optimalBufferSize = (
unsigned int)STDMAX(m_optimalBufferSize, RoundDownToMultipleOf(4096U, m_optimalBufferSize));
589 void StreamTransformationFilter::NextPutMultiple(
const byte *inString,
size_t length)
598 size_t len = m_optimalBufferSize;
602 if (len == m_optimalBufferSize)
604 len = RoundDownToMultipleOf(len, s);
616 void StreamTransformationFilter::NextPutModifiable(byte *inString,
size_t length)
622 void StreamTransformationFilter::LastPut(
const byte *inString,
size_t length)
635 if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize))
640 memcpy(space, inString, length);
641 memset(space + length, 0, blockSize - length);
647 if (minLastBlockSize == 0)
649 if (isForwardTransformation)
650 throw InvalidDataFormat(
"StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified");
652 throw InvalidCiphertext(
"StreamTransformationFilter: ciphertext length is not a multiple of block size");
663 case ONE_AND_ZEROS_PADDING:
671 memcpy(space, inString, length);
672 if (m_padding == PKCS_PADDING)
675 byte pad = byte(s-length);
676 memset(space+length, pad, s-length);
680 space[length] = 0x80;
681 memset(space+length+1, 0, s-length-1);
689 throw InvalidCiphertext(
"StreamTransformationFilter: ciphertext length is not a multiple of block size");
691 if (m_padding == PKCS_PADDING)
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");
700 while (length > 1 && space[length-1] == 0)
702 if (space[--length] != 0x80)
703 throw InvalidCiphertext(
"StreamTransformationFilter: invalid ones-and-zeros padding found");
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)
719 m_digestSize = truncatedDigestSize < 0 ? m_hashModule.DigestSize() : truncatedDigestSize;
723 void HashFilter::IsolatedInitialize(
const NameValuePairs ¶meters)
727 m_digestSize = s < 0 ? m_hashModule.
DigestSize() : s;
730 size_t HashFilter::Put2(
const byte *inString,
size_t length,
int messageEnd,
bool blocking)
734 FILTER_OUTPUT3(1, 0, inString, length, 0, m_messagePutChannel);
735 m_hashModule.
Update(inString, length);
740 m_space = HelpCreatePutSpace(*
AttachedTransformation(), m_hashPutChannel, m_digestSize, m_digestSize, size = m_digestSize);
743 FILTER_OUTPUT3(2, 0, m_space, m_digestSize, messageEnd, m_hashPutChannel);
745 FILTER_END_NO_MESSAGE_END;
757 void HashVerificationFilter::InitializeDerivedAndReturnNewSizes(
const NameValuePairs ¶meters,
size_t &firstSize,
size_t &blockSize,
size_t &lastSize)
761 m_digestSize = s < 0 ? m_hashModule.
DigestSize() : s;
763 firstSize = m_flags & HASH_AT_BEGIN ? m_digestSize : 0;
765 lastSize = m_flags & HASH_AT_BEGIN ? 0 : m_digestSize;
768 void HashVerificationFilter::FirstPut(
const byte *inString)
770 if (m_flags & HASH_AT_BEGIN)
772 m_expectedHash.
New(m_digestSize);
773 memcpy(m_expectedHash, inString, m_expectedHash.size());
774 if (m_flags & PUT_HASH)
779 void HashVerificationFilter::NextPutMultiple(
const byte *inString,
size_t length)
781 m_hashModule.
Update(inString, length);
782 if (m_flags & PUT_MESSAGE)
786 void HashVerificationFilter::LastPut(
const byte *inString,
size_t length)
788 if (m_flags & HASH_AT_BEGIN)
791 m_verified = m_hashModule.
TruncatedVerify(m_expectedHash, m_digestSize);
795 m_verified = (length==m_digestSize && m_hashModule.
TruncatedVerify(inString, length));
796 if (m_flags & PUT_HASH)
800 if (m_flags & PUT_RESULT)
803 if ((m_flags & THROW_EXCEPTION) && !m_verified)
804 throw HashVerificationFailed();
810 bool putAAD,
int truncatedDigestSize,
const std::string &macChannel, BlockPaddingScheme padding)
812 , m_hf(c, new
OutputProxy(*this, false), putAAD, truncatedDigestSize, AAD_CHANNEL, macChannel)
817 void AuthenticatedEncryptionFilter::IsolatedInitialize(
const NameValuePairs ¶meters)
819 m_hf.IsolatedInitialize(parameters);
820 StreamTransformationFilter::IsolatedInitialize(parameters);
823 byte * AuthenticatedEncryptionFilter::ChannelCreatePutSpace(
const std::string &channel,
size_t &size)
828 if (channel == AAD_CHANNEL)
831 throw InvalidChannelName(
"AuthenticatedEncryptionFilter", channel);
834 size_t AuthenticatedEncryptionFilter::ChannelPut2(
const std::string &channel,
const byte *begin,
size_t length,
int messageEnd,
bool blocking)
839 if (channel == AAD_CHANNEL)
840 return m_hf.
Put2(begin, length, 0, blocking);
842 throw InvalidChannelName(
"AuthenticatedEncryptionFilter", channel);
845 void AuthenticatedEncryptionFilter::LastPut(
const byte *inString,
size_t length)
847 StreamTransformationFilter::LastPut(inString, length);
856 , m_streamFilter(c, new
OutputProxy(*this, false), padding, true)
862 void AuthenticatedDecryptionFilter::InitializeDerivedAndReturnNewSizes(
const NameValuePairs ¶meters,
size_t &firstSize,
size_t &blockSize,
size_t &lastSize)
869 firstSize = m_hashVerifier.m_firstSize;
871 lastSize = m_hashVerifier.m_lastSize;
874 byte * AuthenticatedDecryptionFilter::ChannelCreatePutSpace(
const std::string &channel,
size_t &size)
879 if (channel == AAD_CHANNEL)
882 throw InvalidChannelName(
"AuthenticatedDecryptionFilter", channel);
885 size_t AuthenticatedDecryptionFilter::ChannelPut2(
const std::string &channel,
const byte *begin,
size_t length,
int messageEnd,
bool blocking)
894 if (channel == AAD_CHANNEL)
895 return m_hashVerifier.
Put2(begin, length, 0, blocking);
897 throw InvalidChannelName(
"AuthenticatedDecryptionFilter", channel);
900 void AuthenticatedDecryptionFilter::FirstPut(
const byte *inString)
902 m_hashVerifier.
Put(inString, m_firstSize);
905 void AuthenticatedDecryptionFilter::NextPutMultiple(
const byte *inString,
size_t length)
907 m_streamFilter.
Put(inString, length);
910 void AuthenticatedDecryptionFilter::LastPut(
const byte *inString,
size_t length)
912 m_streamFilter.MessageEnd();
913 m_hashVerifier.PutMessageEnd(inString, length);
918 void SignerFilter::IsolatedInitialize(
const NameValuePairs ¶meters)
927 m_messageAccumulator->
Update(inString, length);
929 FILTER_OUTPUT(1, inString, length, 0);
933 m_signer.
Sign(m_rng, m_messageAccumulator.release(), m_buf);
934 FILTER_OUTPUT(2, m_buf, m_buf.size(), messageEnd);
937 FILTER_END_NO_MESSAGE_END;
942 , m_verifier(verifier)
947 void SignatureVerificationFilter::InitializeDerivedAndReturnNewSizes(
const NameValuePairs ¶meters,
size_t &firstSize,
size_t &blockSize,
size_t &lastSize)
954 firstSize = m_flags & SIGNATURE_AT_BEGIN ? size : 0;
956 lastSize = m_flags & SIGNATURE_AT_BEGIN ? 0 : size;
959 void SignatureVerificationFilter::FirstPut(
const byte *inString)
961 if (m_flags & SIGNATURE_AT_BEGIN)
968 memcpy(m_signature, inString, m_signature.size());
971 if (m_flags & PUT_SIGNATURE)
980 void SignatureVerificationFilter::NextPutMultiple(
const byte *inString,
size_t length)
982 m_messageAccumulator->
Update(inString, length);
983 if (m_flags & PUT_MESSAGE)
987 void SignatureVerificationFilter::LastPut(
const byte *inString,
size_t length)
989 if (m_flags & SIGNATURE_AT_BEGIN)
992 m_verifier.
InputSignature(*m_messageAccumulator, m_signature, m_signature.size());
997 m_verifier.
InputSignature(*m_messageAccumulator, inString, length);
999 if (m_flags & PUT_SIGNATURE)
1003 if (m_flags & PUT_RESULT)
1006 if ((m_flags & THROW_EXCEPTION) && !m_verified)
1007 throw SignatureVerificationFailed();
1012 size_t Source::PumpAll2(
bool blocking)
1014 unsigned int messageCount = UINT_MAX;
1016 RETURN_IF_NONZERO(PumpMessages2(messageCount, blocking));
1017 }
while(messageCount == UINT_MAX);
1033 unsigned int Store::CopyMessagesTo(
BufferedTransformation &target,
unsigned int count,
const std::string &channel)
const
1035 if (m_messageEnd || count == 0)
1039 CopyTo(target, ULONG_MAX, channel);
1040 if (GetAutoSignalPropagation())
1041 target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1);
1046 void StringStore::StoreInitialize(
const NameValuePairs ¶meters)
1051 m_store = array.begin();
1052 m_length = array.size();
1059 size_t blockedBytes =
CopyRangeTo2(target, position, transferBytes, channel, blocking);
1060 m_count += (size_t)position;
1061 transferBytes = position;
1062 return blockedBytes;
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);
1072 return blockedBytes;
1075 void RandomNumberStore::StoreInitialize(
const NameValuePairs ¶meters)
1077 parameters.GetRequiredParameter(
"RandomNumberStore",
"RandomNumberGeneratorPointer", m_rng);
1079 parameters.GetRequiredIntParameter(
"RandomNumberStore",
"RandomNumberStoreSize", length);
1086 throw NotImplemented(
"RandomNumberStore: nonblocking transfer is not implemented by this object");
1088 transferBytes = UnsignedMin(transferBytes, m_length - m_count);
1090 m_count += transferBytes;
1097 static const byte nullBytes[128] = {0};
1100 size_t len = (size_t)STDMIN(end-begin, lword(128));
1101 size_t blockedBytes = target.ChannelPut2(channel, nullBytes, len, 0, blocking);
1103 return blockedBytes;
1113 transferBytes = begin;
1115 return blockedBytes;