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; } }
// EGPublicKey::EncryptData // Encrypts a block of specified length into the specified queue. Determines the // number of individual blocks to be encrypted. Adds block count to queue. Then // calls EncryptBlock() to encrypt each block into the queue. Note that mCryptP // must be valid before this method is called. void EGPublicKey::EncryptData(BufferedTransformation& aQueue, const unsigned char* theMsgP, unsigned long theLen) const { WTRACE("EGPublicKey::EncryptData"); WDBG_LL("EGPublicKey::EncryptData, len=" << theLen); // Determine block length and number of blocks unsigned long aBlockLen = mCryptP->MaxPlainTextLength(); unsigned long aNumBlock = theLen / aBlockLen; if ((theLen % aBlockLen) != 0) aNumBlock++; WDBG_LL("EGPublicKey::EncryptBlock NumBlocks=" << aNumBlock << ", BlockLen=" << aBlockLen); // A num blocks to output unsigned long tmpNumBlock = getLittleEndian(aNumBlock); aQueue.Put(reinterpret_cast<unsigned char*>(&tmpNumBlock), sizeof(tmpNumBlock)); // Encrypt the data, one block at a time while (theLen > aBlockLen) { EncryptBlock(aQueue, theMsgP, aBlockLen); theMsgP += aBlockLen; theLen -= aBlockLen; } // Encrypt the last block and close the queue EncryptBlock(aQueue, theMsgP, theLen); aQueue.Close(); }
bool BlockTransformationTest(const CipherFactory &cg, BufferedTransformation &valdata, unsigned int tuples = 0xffff) { HexEncoder output(new FileSink(cout)); SecByteBlock plain(cg.BlockSize()), cipher(cg.BlockSize()), out(cg.BlockSize()), outplain(cg.BlockSize()); SecByteBlock key(cg.KeyLength()); bool pass=true, fail; while (valdata.MaxRetrievable() && tuples--) { valdata.Get(key, cg.KeyLength()); valdata.Get(plain, cg.BlockSize()); valdata.Get(cipher, cg.BlockSize()); apbt transE = cg.NewEncryption(key); transE->ProcessBlock(plain, out); fail = memcmp(out, cipher, cg.BlockSize()) != 0; apbt transD = cg.NewDecryption(key); transD->ProcessBlock(out, outplain); fail=fail || memcmp(outplain, plain, cg.BlockSize()); pass = pass && !fail; cout << (fail ? "FAILED " : "passed "); output.Put(key, cg.KeyLength()); cout << " "; output.Put(outplain, cg.BlockSize()); cout << " "; output.Put(out, cg.BlockSize()); cout << endl; } return pass; }
PEM_Type PEM_GetType(const BufferedTransformation& bt) { const size_t size = bt.MaxRetrievable(); SecByteBlock sb(size); bt.Peek(sb.data(), sb.size()); return PEM_GetType(sb); }
bool PEM_IsEncrypted(BufferedTransformation& bt) { const size_t size = bt.MaxRetrievable(); SecByteBlock sb(size); bt.Peek(sb.data(), sb.size()); return PEM_IsEncrypted(sb); }
void RandomizedTransfer(BufferedTransformation &source, BufferedTransformation &target, bool finish, const std::string &channel=DEFAULT_CHANNEL) { while (source.MaxRetrievable() > (finish ? 0 : 4096)) { byte buf[4096+64]; size_t start = GlobalRNG().GenerateWord32(0, 63); size_t len = GlobalRNG().GenerateWord32(1, UnsignedMin(4096U, 3*source.MaxRetrievable()/2)); len = source.Get(buf+start, len); target.ChannelPut(channel, buf+start, len); } }
bool TestFilter(BufferedTransformation &bt, const byte *in, size_t inLen, const byte *out, size_t outLen) { FilterTester *ft; bt.Attach(ft = new FilterTester(out, outLen)); while (inLen) { size_t randomLen = GlobalRNG().GenerateWord32(0, (word32)inLen); bt.Put(in, randomLen); in += randomLen; inLen -= randomLen; } bt.MessageEnd(); return ft->GetResult(); }
inline size_t TransferTo(BufferedTransformation &target, lword transferMax, const std::string &channel=DEFAULT_CHANNEL) { size_t len = UnsignedMin(m_tail-m_head, transferMax); target.ChannelPutModifiable(channel, buf+m_head, len); m_head += len; return len; }
void DL_GroupParameters_EC<EC>::BERDecode(BufferedTransformation &bt) { byte b; if (!bt.Peek(b)) BERDecodeError(); if (b == OBJECT_IDENTIFIER) Initialize(OID(bt)); else { BERSequenceDecoder seq(bt); word32 version; BERDecodeUnsigned<word32>(seq, version, INTEGER, 1, 1); // check version EllipticCurve ec(seq); Point G = ec.BERDecodePoint(seq); Integer n(seq); Integer k; bool cofactorPresent = !seq.EndReached(); if (cofactorPresent) k.BERDecode(seq); else k = Integer::Zero(); seq.MessageEnd(); Initialize(ec, G, n, k); } }
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; }
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 BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking) { if (AttachedTransformation()) return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking); else { unsigned int maxMessages = messageCount; for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++) { unsigned int blockedBytes; unsigned long transferredBytes; while (AnyRetrievable()) { transferredBytes = ULONG_MAX; blockedBytes = TransferTo2(target, transferredBytes, channel, blocking); if (blockedBytes > 0) return blockedBytes; } if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking)) return 1; bool result = GetNextMessage(); assert(result); } return 0; } }
inline unsigned int TransferTo(BufferedTransformation &target, const std::string &channel=BufferedTransformation::NULL_CHANNEL) { unsigned int len = m_tail-m_head; target.ChannelPutModifiable(channel, buf+m_head, len); m_head = m_tail; return len; }
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; } }
inline size_t TransferTo(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL) { size_t len = m_tail-m_head; target.ChannelPutModifiable(channel, buf+m_head, len); m_head = m_tail; return len; }
void BufferedTransformation::TransferTo(BufferedTransformation &target) { SecByteBlock buf(256); unsigned int l; while ((l=Get(buf, 256)) != 0) target.Put(buf, l); }
void EC2N::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const { if (P.identity) NullStore().TransferTo(bt, EncodedPointSize(compressed)); else if (compressed) { bt.Put(2 + (!P.x ? 0 : m_field->Divide(P.y, P.x).GetBit(0))); P.x.Encode(bt, m_field->MaxElementByteLength()); } else { unsigned int len = m_field->MaxElementByteLength(); bt.Put(4); // uncompressed P.x.Encode(bt, len); P.y.Encode(bt, len); } }
void ECP::EncodePoint(BufferedTransformation &bt, const Point &P, bool compressed) const { if (P.identity) NullStore().TransferTo(bt, EncodedPointSize(compressed)); else if (compressed) { bt.Put(2 + P.y.GetBit(0)); P.x.Encode(bt, GetField().MaxElementByteLength()); } else { unsigned int len = GetField().MaxElementByteLength(); bt.Put(4); // uncompressed P.x.Encode(bt, len); P.y.Encode(bt, len); } }
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; }
size_t StringStore::CopyRangeTo2(BufferedTransformation &target, lword &begin, lword end, const std::string &channel, bool blocking) const { size_t i = UnsignedMin(m_length, m_count+begin); size_t len = UnsignedMin(m_length-i, end-begin); size_t blockedBytes = target.ChannelPut2(channel, m_store+i, len, 0, blocking); if (!blockedBytes) begin += len; return blockedBytes; }
// EGPublicKey::EncryptBlock // Encrypts a block of specified length into the specified queue. This method is // called by the EncryptData() method for each block. Note that theLen MUST NOT exceed // the max block size of the mCryptP object (EncryptData enforces this). Also note that // mCryptP must be valid before this method is called. void EGPublicKey::EncryptBlock(BufferedTransformation& aQueue, const unsigned char* theBlockP, unsigned long theLen) const { WTRACE("EGPublicKey::EncryptBlock"); WDBG_LL("EGPublicKey::EncryptBlock, len=" << theLen << ", cipherlen=" << mCryptP->CipherTextLength()); auto_ptr<unsigned char> aBuf(new unsigned char[mCryptP->CipherTextLength()]); mCryptP->Encrypt(Randomizer::GetPool(), theBlockP, theLen, aBuf.get()); aQueue.Put(aBuf.get(), mCryptP->CipherTextLength()); }
void PEM_LoadPrivateKey(BufferedTransformation& src, PKCS8PrivateKey& key) { key.BERDecodePrivateKey(src, 0, src.MaxRetrievable()); #if PEM_KEY_OR_PARAMETER_VALIDATION AutoSeededRandomPool prng; if(!key.Validate(prng, 2)) throw Exception(Exception::OTHER_ERROR, "PEM_LoadPrivateKey: key validation failed"); #endif }
unsigned int RandomNumberStore::TransferTo2(BufferedTransformation &target, unsigned long &transferBytes, const std::string &channel, bool blocking) { if (!blocking) throw NotImplemented("RandomNumberStore: nonblocking transfer is not implemented by this object"); unsigned long transferMax = transferBytes; for (transferBytes = 0; transferBytes<transferMax && m_count < (unsigned long)m_length; ++transferBytes, ++m_count) target.ChannelPut(channel, m_rng->GenerateByte()); return 0; }
size_t ByteQueue::Walker::TransferTo2(BufferedTransformation &target, lword &transferBytes, const std::string &channel, bool blocking) { lword bytesLeft = transferBytes; size_t blockedBytes = 0; while (m_node) { size_t len = (size_t)STDMIN(bytesLeft, (lword)m_node->CurrentSize()-m_offset); blockedBytes = target.ChannelPut2(channel, m_node->buf+m_node->m_head+m_offset, len, 0, blocking); if (blockedBytes) goto done; m_position += len; bytesLeft -= len; if (!bytesLeft) { m_offset += len; goto done; } m_node = m_node->next; m_offset = 0; } if (bytesLeft && m_lazyLength) { size_t len = (size_t)STDMIN(bytesLeft, (lword)m_lazyLength); blockedBytes = target.ChannelPut2(channel, m_lazyString, len, 0, blocking); if (blockedBytes) goto done; m_lazyString += len; m_lazyLength -= len; bytesLeft -= len; } done: transferBytes -= bytesLeft; return blockedBytes; }
void PolynomialMod2::Decode(BufferedTransformation &bt, size_t inputLen) { reg.CleanNew(BytesToWords(inputLen)); for (size_t i=inputLen; i > 0; i--) { byte b; bt.Get(b); reg[(i-1)/WORD_SIZE] |= word(b) << ((i-1)%WORD_SIZE)*8; } }
void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length) { FixedSizeSecBlock<byte, 256> buffer; while (length) { size_t len = UnsignedMin(buffer.size(), length); GenerateBlock(buffer, len); target.ChannelPut(channel, buffer, len); length -= len; } }
void OldRandomPool::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword size) { while (size > 0) { if (getPos == pool.size()) Stir(); size_t t = UnsignedMin(pool.size() - getPos, size); target.ChannelPut(channel, pool+getPos, t); size -= t; getPos += t; }}
unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count) const { if (m_messageEnd || count == 0) return 0; else { CopyTo(target); if (GetAutoSignalPropagation()) target.MessageEnd(GetAutoSignalPropagation()-1); return 1; } }
unsigned int FileStore::CopyRangeTo2(BufferedTransformation &target, unsigned long &begin, unsigned long end, const std::string &channel, bool blocking) const { if (!m_stream) return 0; if (begin == 0 && end == 1) { int result = m_stream->peek(); if (result == EOF) // GCC workaround: 2.95.2 doesn't have char_traits<char>::eof() return 0; else { unsigned int blockedBytes = target.ChannelPut(channel, byte(result), blocking); begin += 1-blockedBytes; return blockedBytes; } } // TODO: figure out what happens on cin streampos current = m_stream->tellg(); streampos endPosition = m_stream->seekg(0, ios::end).tellg(); streampos newPosition = current + (streamoff)begin; if (newPosition >= endPosition) { m_stream->seekg(current); return 0; // don't try to seek beyond the end of file } m_stream->seekg(newPosition); unsigned long total = 0; try { assert(!m_waiting); unsigned long copyMax = end-begin; unsigned int blockedBytes = const_cast<FileStore *>(this)->TransferTo2(target, copyMax, channel, blocking); begin += copyMax; if (blockedBytes) { const_cast<FileStore *>(this)->m_waiting = false; return blockedBytes; } } catch(...) { m_stream->clear(); m_stream->seekg(current); throw; } m_stream->clear(); m_stream->seekg(current); return 0; }
unsigned int Store::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const { if (m_messageEnd || count == 0) return 0; else { CopyTo(target, ULONG_MAX, channel); if (GetAutoSignalPropagation()) target.ChannelMessageEnd(channel, GetAutoSignalPropagation()-1); return 1; } }