unsigned long NullStore::CopyTo(BufferedTransformation &target, unsigned long copyMax) const { static byte nullBytes[128]; for (unsigned long i=0; i<copyMax; i+=STDMIN(copyMax-i, 128UL)) target.Put(nullBytes, STDMIN(copyMax-i, 128UL)); return copyMax; }
byte X917RNG::GenerateByte() { if (randbuf_counter==0) { // calculate new enciphered timestamp if (m_deterministicTimeVector) { xorbuf(dtbuf, (byte *)&m_deterministicTimeVector, STDMIN((int)sizeof(m_deterministicTimeVector), S)); while (++m_deterministicTimeVector == 0) {} // skip 0 } else { clock_t tstamp = clock(); xorbuf(dtbuf, (byte *)&tstamp, STDMIN((int)sizeof(tstamp), S)); } cipher->ProcessBlock(dtbuf); // combine enciphered timestamp with seed xorbuf(randseed, dtbuf, S); // generate a new block of random bytes cipher->ProcessBlock(randseed, randbuf); // compute new seed vector for (int i=0; i<S; i++) randseed[i] = randbuf[i] ^ dtbuf[i]; cipher->ProcessBlock(randseed); randbuf_counter=S; } return(randbuf[--randbuf_counter]); }
unsigned int StringStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const { unsigned int i = (unsigned int)STDMIN((unsigned long)m_count+begin, (unsigned long)m_length); unsigned int len = (unsigned int)STDMIN((unsigned long)m_length-i, end-begin); unsigned int blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking); if (!blockedBytes) begin += len; return blockedBytes; }
const byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(unsigned int &numberOfBlocks) { numberOfBlocks = STDMIN(numberOfBlocks, STDMIN((unsigned int)(m_buffer.End()-m_begin), m_size)/m_blockSize); const byte *ptr = m_begin; if ((m_begin+=m_blockSize*numberOfBlocks) == m_buffer.End()) m_begin = m_buffer; m_size -= m_blockSize*numberOfBlocks; return ptr; }
byte *FilterWithBufferedInput::BlockQueue::GetContigousBlocks(size_t &numberOfBytes) { numberOfBytes = STDMIN(numberOfBytes, STDMIN(size_t(m_buffer.end()-m_begin), m_size)); byte *ptr = m_begin; m_begin += numberOfBytes; m_size -= numberOfBytes; if (m_size == 0 || m_begin == m_buffer.end()) m_begin = m_buffer; return ptr; }
void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target) { std::string s1 = GetRequiredDatum(data, name), s2; ByteQueue q; while (!s1.empty()) { while (s1[0] == ' ') { s1 = s1.substr(1); if (s1.empty()) goto end; // avoid invalid read if s1 is empty } int repeat = 1; if (s1[0] == 'r') { repeat = atoi(s1.c_str()+1); s1 = s1.substr(s1.find(' ')+1); } s2 = ""; // MSVC 6 doesn't have clear(); if (s1[0] == '\"') { s2 = s1.substr(1, s1.find('\"', 1)-1); s1 = s1.substr(s2.length() + 2); } else if (s1.substr(0, 2) == "0x") { StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2))); s1 = s1.substr(STDMIN(s1.find(' '), s1.length())); } else { StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2))); s1 = s1.substr(STDMIN(s1.find(' '), s1.length())); } while (repeat--) { q.Put((const byte *)s2.data(), s2.size()); RandomizedTransfer(q, target, false); } } end: RandomizedTransfer(q, target, true); }
void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length) { if (m_leftOver > 0) { const size_t len = STDMIN(m_leftOver, length); memcpy(outString, PtrSub(KeystreamBufferEnd(), m_leftOver), len); length -= len; m_leftOver -= len; outString = PtrAdd(outString, len); if (!length) {return;} } PolicyInterface &policy = this->AccessPolicy(); unsigned int bytesPerIteration = policy.GetBytesPerIteration(); if (length >= bytesPerIteration) { const size_t iterations = length / bytesPerIteration; policy.WriteKeystream(outString, iterations); length -= iterations * bytesPerIteration; outString = PtrAdd(outString, iterations * bytesPerIteration); } if (length > 0) { size_t bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration); size_t bufferIterations = bufferByteSize / bytesPerIteration; policy.WriteKeystream(PtrSub(KeystreamBufferEnd(), bufferByteSize), bufferIterations); memcpy(outString, PtrSub(KeystreamBufferEnd(), bufferByteSize), length); m_leftOver = bufferByteSize - length; } }
unsigned int ByteQueueNode::Get(byte *outString, unsigned int getMax) { unsigned int l = STDMIN(getMax, tail-head); memcpy(outString, buf+head, l); head += l; return l; }
unsigned int ByteQueueNode::Put(const byte *inString, unsigned int length) { unsigned int l = STDMIN(length, MaxSize()-tail); memcpy(buf+tail, inString, l); tail += l; return l; }
void Inflator::OutputPast(unsigned int length, unsigned int distance) { if (distance > m_maxDistance) throw BadBlockErr(); unsigned int start; if (m_current > distance) start = m_current - distance; else start = m_current + m_window.size - distance; if (start + length > m_window.size) { for (; start < m_window.size; start++, length--) OutputByte(m_window[start]); start = 0; } if (start + length > m_current || m_current + length >= m_window.size) { while (length--) OutputByte(m_window[start++]); } else { memcpy(m_window + m_current, m_window + start, length); m_current += length; m_maxDistance = STDMIN(m_window.size, m_maxDistance + length); } }
size_t Grouper::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) { FILTER_BEGIN; if (m_groupSize) { while (m_inputPosition < length) { if (m_counter == m_groupSize) { FILTER_OUTPUT(1, m_separator, m_separator.size(), 0); m_counter = 0; } size_t len; FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter), begin+m_inputPosition, len, 0); m_inputPosition += len; m_counter += len; } } else FILTER_OUTPUT(3, begin, length, 0); if (messageEnd) { FILTER_OUTPUT(4, m_terminator, m_terminator.size(), messageEnd); m_counter = 0; } FILTER_END_NO_MESSAGE_END }
unsigned long RandomNumberStore::CopyTo(BufferedTransformation &target, unsigned long copyMax) const { unsigned int len = (unsigned int)STDMIN((unsigned long)(m_length-m_count), copyMax); for (unsigned int i=0; i<len; i++) target.Put(m_rng.GenerateByte()); return len; }
unsigned int MessageQueue::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking) { transferBytes = STDMIN(MaxRetrievable(), transferBytes); unsigned int blockedBytes = m_queue.TransferTo2(target, transferBytes, channel, blocking); m_lengths.front() -= transferBytes; return blockedBytes; }
inline unsigned int TransferTo(BufferedTransformation &target, unsigned int transferMax, const std::string &channel=BufferedTransformation::NULL_CHANNEL) { unsigned int len = STDMIN(transferMax, m_tail-m_head); target.ChannelPutModifiable(channel, buf+m_head, len); m_head += len; return len; }
unsigned int Grouper::Put2(const byte *begin, unsigned int length, int messageEnd, bool blocking) { if (m_groupSize) { FILTER_BEGIN; while (m_inputPosition < length) { if (m_counter == m_groupSize) { FILTER_OUTPUT(1, m_seperator, m_seperator.size(), 0); m_counter = 0; } unsigned int len; FILTER_OUTPUT2(2, len = STDMIN(length-m_inputPosition, m_groupSize-m_counter), begin+m_inputPosition, len, 0); m_inputPosition += len; m_counter += len; } if (messageEnd) FILTER_OUTPUT(3, m_terminator, m_terminator.size(), messageEnd); FILTER_END_NO_MESSAGE_END } else return Output(0, begin, length, messageEnd, blocking);
unsigned int ByteQueue::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking) { if (blocking) { unsigned long bytesLeft = transferBytes; for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->next) bytesLeft -= current->TransferTo(target, bytesLeft, channel); CleanupUsedNodes(); unsigned int len = (unsigned int)STDMIN(bytesLeft, (unsigned long)m_lazyLength); if (len) { target.ChannelPut(channel, m_lazyString, len); m_lazyString += len; m_lazyLength -= len; bytesLeft -= len; } transferBytes -= bytesLeft; return 0; } else { Walker walker(*this); unsigned int blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); Skip(transferBytes); return blockedBytes; } }
size_t ByteQueue::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) { if (blocking) { lword bytesLeft = transferBytes; for (ByteQueueNode *current=m_head; bytesLeft && current; current=current->next) bytesLeft -= current->TransferTo(target, bytesLeft, channel); CleanupUsedNodes(); size_t len = (size_t)STDMIN(bytesLeft, (lword)m_lazyLength); if (len) { if (m_lazyStringModifiable) target.ChannelPutModifiable(channel, m_lazyString, len); else target.ChannelPut(channel, m_lazyString, len); m_lazyString += len; m_lazyLength -= len; bytesLeft -= len; } transferBytes -= bytesLeft; return 0; } else { Walker walker(*this); size_t blockedBytes = walker.TransferTo2(target, transferBytes, channel, blocking); Skip(transferBytes); return blockedBytes; } }
void PrimeSieve::DoSieve() { BuildPrimeTable(); const unsigned int maxSieveSize = 32768; unsigned int sieveSize = STDMIN(Integer(maxSieveSize), (m_last-m_first)/m_step+1).ConvertToLong(); m_sieve.clear(); m_sieve.resize(sieveSize, false); if (m_delta == 0) { for (unsigned int i = 0; i < primeTableSize; ++i) SieveSingle(m_sieve, primeTable[i], m_first, m_step, m_step.InverseMod(primeTable[i])); } else { assert(m_step%2==0); Integer qFirst = (m_first-m_delta) >> 1; Integer halfStep = m_step >> 1; for (unsigned int i = 0; i < primeTableSize; ++i) { word p = primeTable[i]; word stepInv = m_step.InverseMod(p); SieveSingle(m_sieve, p, m_first, m_step, stepInv); word halfStepInv = 2*stepInv < p ? 2*stepInv : 2*stepInv-p; SieveSingle(m_sieve, p, qFirst, halfStep, halfStepInv); } } }
size_t ArraySink::Put2(const byte *begin, size_t length, int messageEnd, bool blocking) { if (m_buf+m_total != begin) memcpy(m_buf+m_total, begin, STDMIN(length, SaturatingSubtract(m_size, m_total))); m_total += length; return 0; }
unsigned int MessageQueue::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const { if (begin >= MaxRetrievable()) return 0; return m_queue.CopyRangeTo2(target, begin, STDMIN(MaxRetrievable(), end), channel, blocking); }
/* inline unsigned int Put(byte inByte) { if (MaxSize()==m_tail) return 0; buf[m_tail++]=inByte; return 1; } */ inline unsigned int Put(const byte *begin, unsigned int length) { unsigned int l = STDMIN(length, MaxSize()-m_tail); memcpy(buf+m_tail, begin, l); m_tail += l; return l; }
NetworkSink::NetworkSink(unsigned int maxBufferSize, unsigned int autoFlushBound) : m_maxBufferSize(maxBufferSize), m_autoFlushBound(autoFlushBound) , m_needSendResult(false), m_wasBlocked(false), m_eofState(EOF_NONE) , m_buffer(STDMIN(16U*1024U+256, maxBufferSize)), m_skipBytes(0) , m_speedTimer(Timer::MILLISECONDS), m_byteCountSinceLastTimerReset(0) , m_currentSpeed(0), m_maxObservedSpeed(0) { }
inline size_t Put(const byte *begin, size_t length) { size_t l = STDMIN(length, MaxSize()-m_tail); if (buf+m_tail != begin) memcpy(buf+m_tail, begin, l); m_tail += l; return l; }
bool WaitObjectContainer::Wait(unsigned long milliseconds) { if (m_noWait || m_handles.empty()) return true; if (m_handles.size() > MAXIMUM_WAIT_OBJECTS) { // too many wait objects for a single WaitForMultipleObjects call, so use multiple threads static const unsigned int WAIT_OBJECTS_PER_THREAD = MAXIMUM_WAIT_OBJECTS-1; unsigned int nThreads = (m_handles.size() + WAIT_OBJECTS_PER_THREAD - 1) / WAIT_OBJECTS_PER_THREAD; if (nThreads > MAXIMUM_WAIT_OBJECTS) // still too many wait objects, maybe implement recursive threading later? throw Err("WaitObjectContainer: number of wait objects exceeds limit"); CreateThreads(nThreads); DWORD error = S_OK; for (unsigned int i=0; i<m_threads.size(); i++) { WaitingThreadData &thread = *m_threads[i]; while (!thread.waitingToWait) // spin until thread is in the initial "waiting to wait" state Sleep(0); if (i<nThreads) { thread.waitHandles = &m_handles[i*WAIT_OBJECTS_PER_THREAD]; thread.count = STDMIN(WAIT_OBJECTS_PER_THREAD, m_handles.size() - i*WAIT_OBJECTS_PER_THREAD); thread.error = &error; } else thread.count = 0; } ResetEvent(m_stopWaiting); PulseEvent(m_startWaiting); DWORD result = ::WaitForSingleObject(m_stopWaiting, milliseconds); if (result == WAIT_OBJECT_0) { if (error == S_OK) return true; else throw Err("WaitObjectContainer: WaitForMultipleObjects failed with error " + IntToString(error)); } SetEvent(m_stopWaiting); if (result == WAIT_TIMEOUT) return false; else throw Err("WaitObjectContainer: WaitForSingleObject failed with error " + IntToString(::GetLastError())); } else { DWORD result = ::WaitForMultipleObjects(m_handles.size(), &m_handles[0], FALSE, milliseconds); if (result >= WAIT_OBJECT_0 && result < WAIT_OBJECT_0 + m_handles.size()) return true; else if (result == WAIT_TIMEOUT) return false; else throw Err("WaitObjectContainer: WaitForMultipleObjects failed with error " + IntToString(::GetLastError())); } }
void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length) { if (m_leftOver > 0) { size_t len = STDMIN(m_leftOver, length); xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len); length -= len; m_leftOver -= len; inString += len; outString += len; if (!length) return; } CRYPTOPP_ASSERT(m_leftOver == 0); PolicyInterface &policy = this->AccessPolicy(); unsigned int bytesPerIteration = policy.GetBytesPerIteration(); if (policy.CanOperateKeystream() && length >= bytesPerIteration) { size_t iterations = length / bytesPerIteration; unsigned int alignment = policy.GetAlignment(); KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment)); policy.OperateKeystream(operation, outString, inString, iterations); inString += iterations * bytesPerIteration; outString += iterations * bytesPerIteration; length -= iterations * bytesPerIteration; if (!length) return; } size_t bufferByteSize = m_buffer.size(); size_t bufferIterations = bufferByteSize / bytesPerIteration; while (length >= bufferByteSize) { policy.WriteKeystream(m_buffer, bufferIterations); xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize); length -= bufferByteSize; inString += bufferByteSize; outString += bufferByteSize; } if (length > 0) { bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration); bufferIterations = bufferByteSize / bytesPerIteration; policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations); xorbuf(outString, inString, KeystreamBufferEnd()-bufferByteSize, length); m_leftOver = bufferByteSize - length; } }
inline void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, unsigned int length) { if (m_leftOver > 0) { unsigned int len = STDMIN(m_leftOver, length); xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len); length -= len; m_leftOver -= len; inString += len; outString += len; } if (!length) return; assert(m_leftOver == 0); PolicyInterface &policy = this->AccessPolicy(); unsigned int bytesPerIteration = policy.GetBytesPerIteration(); unsigned int alignment = policy.GetAlignment(); if (policy.CanOperateKeystream() && length >= bytesPerIteration && IsAlignedOn(outString, alignment)) { if (IsAlignedOn(inString, alignment)) policy.OperateKeystream(XOR_KEYSTREAM, outString, inString, length / bytesPerIteration); else { memcpy(outString, inString, length); policy.OperateKeystream(XOR_KEYSTREAM_INPLACE, outString, outString, length / bytesPerIteration); } inString += length - length % bytesPerIteration; outString += length - length % bytesPerIteration; length %= bytesPerIteration; if (!length) return; } unsigned int bufferByteSize = GetBufferByteSize(policy); unsigned int bufferIterations = policy.GetIterationsToBuffer(); while (length >= bufferByteSize) { policy.WriteKeystream(m_buffer, bufferIterations); xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize); length -= bufferByteSize; inString += bufferByteSize; outString += bufferByteSize; } if (length > 0) { policy.WriteKeystream(m_buffer, bufferIterations); xorbuf(outString, inString, KeystreamBufferBegin(), length); m_leftOver = bytesPerIteration - length; } }
void PutDecodedDatumInto(const TestData &data, const char *name, BufferedTransformation &target) { std::string s1 = GetRequiredDatum(data, name), s2; while (!s1.empty()) { while (s1[0] == ' ') s1 = s1.substr(1); int repeat = 1; if (s1[0] == 'r') { repeat = atoi(s1.c_str()+1); s1 = s1.substr(s1.find(' ')+1); } s2 = ""; // MSVC 6 doesn't have clear(); if (s1[0] == '\"') { s2 = s1.substr(1, s1.find('\"', 1)-1); s1 = s1.substr(s2.length() + 2); } else if (s1.substr(0, 2) == "0x") { StringSource(s1.substr(2, s1.find(' ')), true, new HexDecoder(new StringSink(s2))); s1 = s1.substr(STDMIN(s1.find(' '), s1.length())); } else { StringSource(s1.substr(0, s1.find(' ')), true, new HexDecoder(new StringSink(s2))); s1 = s1.substr(STDMIN(s1.find(' '), s1.length())); } ByteQueue q; while (repeat--) { q.Put((const byte *)s2.data(), s2.size()); if (q.MaxRetrievable() > 4*1024 || repeat == 0) q.TransferTo(target); } } }
unsigned int FileSource::Pump(unsigned int size) { unsigned int total=0; SecByteBlock buffer(STDMIN(size, BUFFER_SIZE)); while (size && in.good()) { in.read((char *)buffer.ptr, STDMIN(size, BUFFER_SIZE)); unsigned l = in.gcount(); outQueue->Put(buffer, l); size -= l; total += l; } if (!in.good() && !in.eof()) throw ReadErr(); return total; }
inline size_t Put(const byte *begin, size_t length) { // Avoid passing NULL to memcpy if (!begin || !length) return length; size_t l = STDMIN(length, MaxSize()-m_tail); if (m_buf+m_tail != begin) memcpy(m_buf+m_tail, begin, l); m_tail += l; return l; }
void FilterWithBufferedInput::BlockQueue::Put(const byte *inString, size_t length) { assert(m_size + length <= m_buffer.size()); byte *end = (m_size < size_t(m_buffer.end()-m_begin)) ? m_begin + m_size : m_begin + m_size - m_buffer.size(); size_t len = STDMIN(length, size_t(m_buffer.end()-end)); memcpy(end, inString, len); if (len < length) memcpy(m_buffer, inString+len, length-len); m_size += length; }