void StreamTransformationFilter::NextPutMultiple(const byte *inString, size_t length) { if (!length) return; size_t s = m_cipher.MandatoryBlockSize(); do { size_t len = m_optimalBufferSize; byte *space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, length, len); if (len < length) { if (len == m_optimalBufferSize) len -= m_cipher.GetOptimalBlockSizeUsed(); len = RoundDownToMultipleOf(len, s); } else len = length; m_cipher.ProcessString(space, inString, len); AttachedTransformation()->PutModifiable(space, len); inString += len; length -= len; } while (length > 0); }
unsigned int HashFilter::Put2(const byte *inString, unsigned int length, int messageEnd, bool blocking) { FILTER_BEGIN; m_hashModule.Update(inString, length); if (m_putMessage) FILTER_OUTPUT(1, inString, length, 0); if (messageEnd) { { unsigned int size, digestSize = m_hashModule.DigestSize(); m_space = HelpCreatePutSpace(*AttachedTransformation(), NULL_CHANNEL, digestSize, digestSize, size = digestSize); m_hashModule.Final(m_space); } FILTER_OUTPUT(2, m_space, m_hashModule.DigestSize(), messageEnd); } FILTER_END_NO_MESSAGE_END; }
size_t HashFilter::Put2(const byte *inString, size_t length, int messageEnd, bool blocking) { FILTER_BEGIN; if (m_putMessage) FILTER_OUTPUT3(1, 0, inString, length, 0, m_messagePutChannel); m_hashModule.Update(inString, length); if (messageEnd) { { size_t size; m_space = HelpCreatePutSpace(*AttachedTransformation(), m_hashPutChannel, m_digestSize, m_digestSize, size = m_digestSize); m_hashModule.TruncatedFinal(m_space, m_digestSize); } FILTER_OUTPUT3(2, 0, m_space, m_digestSize, messageEnd, m_hashPutChannel); } FILTER_END_NO_MESSAGE_END; }
size_t RubyIOStore::TransferTo2(BufferedTransformation& target, CryptoPP::lword& transferBytes, const std::string& channel, bool blocking) { if (!m_stream) { transferBytes = 0; return 0; } lword size = transferBytes; transferBytes = 0; if (m_waiting) { goto output; } while (size && !RTEST(rb_funcall(*m_stream, rb_intern("eof?"), 0))) { { VALUE buffer; size_t spaceSize = 1024; m_space = HelpCreatePutSpace(target, channel, 1, UnsignedMin(size_t(0) - 1, size), spaceSize); buffer = rb_funcall(*m_stream, rb_intern("read"), 1, UINT2NUM(STDMIN(size, (lword) spaceSize))); if (TYPE(buffer) != T_STRING) { throw ReadErr(); } memcpy(m_space, StringValuePtr(buffer), RSTRING_LEN(buffer)); m_len = RSTRING_LEN(buffer); } size_t blockedBytes; output: blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking); m_waiting = blockedBytes > 0; if (m_waiting) { return blockedBytes; } size -= m_len; transferBytes += m_len; } if (!RTEST(rb_funcall(*m_stream, rb_intern("eof?"), 0))) { throw ReadErr(); } return 0; }
size_t FileStore::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) { if (!m_stream) { transferBytes = 0; return 0; } lword size=transferBytes; transferBytes = 0; if (m_waiting) goto output; while (size && m_stream->good()) { { size_t spaceSize = 1024; m_space = HelpCreatePutSpace(target, channel, 1, UnsignedMin(size_t(SIZE_MAX), size), spaceSize); m_stream->read((char *)m_space, (unsigned int)STDMIN(size, (lword)spaceSize)); } m_len = (size_t)m_stream->gcount(); size_t blockedBytes; output: blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking); m_waiting = blockedBytes > 0; if (m_waiting) return blockedBytes; size -= m_len; transferBytes += m_len; } if (!m_stream->good() && !m_stream->eof()) throw ReadErr(); return 0; }
unsigned int RageFileStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking) { if( !m_file.IsGood() ) { transferBytes = 0; return 0; } unsigned long size=transferBytes; transferBytes = 0; if (m_waiting) goto output; while( size && !m_file.AtEOF() ) { { unsigned int spaceSize = 1024; m_space = HelpCreatePutSpace(target, channel, 1, (unsigned int)STDMIN(size, (unsigned long)UINT_MAX), spaceSize); m_len = m_file.Read( (char *)m_space, STDMIN(size, (unsigned long)spaceSize)); if( m_len == -1 ) throw ReadErr( m_file ); } unsigned int blockedBytes; output: blockedBytes = target.ChannelPutModifiable2(channel, m_space, m_len, 0, blocking); m_waiting = blockedBytes > 0; if (m_waiting) return blockedBytes; size -= m_len; transferBytes += m_len; } return 0; }
void StreamTransformationFilter::LastPut(const byte *inString, size_t length) { byte *space = NULL; switch (m_padding) { case NO_PADDING: case ZEROS_PADDING: if (length > 0) { size_t minLastBlockSize = m_cipher.MinLastBlockSize(); bool isForwardTransformation = m_cipher.IsForwardTransformation(); if (isForwardTransformation && m_padding == ZEROS_PADDING && (minLastBlockSize == 0 || length < minLastBlockSize)) { // do padding size_t blockSize = STDMAX(minLastBlockSize, (size_t)m_cipher.MandatoryBlockSize()); space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, blockSize); if (inString) {memcpy(space, inString, length);} memset(space + length, 0, blockSize - length); m_cipher.ProcessLastBlock(space, space, blockSize); AttachedTransformation()->Put(space, blockSize); } else { if (minLastBlockSize == 0) { if (isForwardTransformation) throw InvalidDataFormat("StreamTransformationFilter: plaintext length is not a multiple of block size and NO_PADDING is specified"); else throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); } space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, length, m_optimalBufferSize); m_cipher.ProcessLastBlock(space, inString, length); AttachedTransformation()->Put(space, length); } } break; case PKCS_PADDING: case ONE_AND_ZEROS_PADDING: unsigned int s; s = m_cipher.MandatoryBlockSize(); assert(s > 1); space = HelpCreatePutSpace(*AttachedTransformation(), DEFAULT_CHANNEL, s, m_optimalBufferSize); if (m_cipher.IsForwardTransformation()) { assert(length < s); if (inString) {memcpy(space, inString, length);} if (m_padding == PKCS_PADDING) { assert(s < 256); byte pad = byte(s-length); memset(space+length, pad, s-length); } else { space[length] = 0x80; memset(space+length+1, 0, s-length-1); } m_cipher.ProcessData(space, space, s); AttachedTransformation()->Put(space, s); } else { if (length != s) throw InvalidCiphertext("StreamTransformationFilter: ciphertext length is not a multiple of block size"); m_cipher.ProcessData(space, inString, s); if (m_padding == PKCS_PADDING) { byte pad = space[s-1]; if (pad < 1 || pad > s || std::find_if(space+s-pad, space+s, std::bind2nd(std::not_equal_to<byte>(), pad)) != space+s) throw InvalidCiphertext("StreamTransformationFilter: invalid PKCS #7 block padding found"); length = s-pad; } else { while (length > 1 && space[length-1] == 0) --length; if (space[--length] != 0x80) throw InvalidCiphertext("StreamTransformationFilter: invalid ones-and-zeros padding found"); } AttachedTransformation()->Put(space, length); } break; default: assert(false); } }