- Main Page
- Namespaces
- Classes
- Files

- File List
- File Members

# cryptlib.cpp

    00001 // cryptlib.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004
    00005 #ifndef CRYPTOPP_IMPORTS
    00006
    00007 #include "cryptlib.h"
    00008 #include "misc.h"
    00009 #include "filters.h"
    00010 #include "algparam.h"
    00011 #include "fips140.h"
    00012 #include "argnames.h"
    00013 #include "fltrimpl.h"
    00014 #include "trdlocal.h"
    00015 #include "osrng.h"
    00016
    00017 #include <memory>
    00018
    00019 NAMESPACE_BEGIN(CryptoPP)
    00020
    00021 CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1);
    00022 CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2);
    00023 CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4);
    00024 #ifdef WORD64_AVAILABLE
    00025 CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8);
    00026 #endif
    00027 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
    00028 CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word));
    00029 #endif
    00030
    00031 const std::string BufferedTransformation::NULL_CHANNEL;
    00032 const NullNameValuePairs g_nullNameValuePairs;
    00033
    00034 BufferedTransformation & TheBitBucket()
    00035 {
    00036         static BitBucket bitBucket;
    00037         return bitBucket;
    00038 }
    00039
    00040 Algorithm::Algorithm(bool checkSelfTestStatus)
    00041 {
    00042         if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled())
    00043         {
    00044                 if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread())
    00045                         throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed.");
    00046
    00047                 if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED)
    00048                         throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed.");
    00049         }
    00050 }
    00051
    00052 void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs &params)
    00053 {
    00054         this->ThrowIfInvalidKeyLength(length);
    00055         this->UncheckedSetKey(key, (unsigned int)length, params);
    00056 }
    00057
    00058 void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds)
    00059 {
    00060         SetKey(key, length, MakeParameters(Name::Rounds(), rounds));
    00061 }
    00062
    00063 void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv)
    00064 {
    00065         SetKey(key, length, MakeParameters(Name::IV(), iv));
    00066 }
    00067
    00068 void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length)
    00069 {
    00070         if (!IsValidKeyLength(length))
    00071                 throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length);
    00072 }
    00073
    00074 void SimpleKeyingInterface::ThrowIfResynchronizable()
    00075 {
    00076         if (IsResynchronizable())
    00077                 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV");
    00078 }
    00079
    00080 void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv)
    00081 {
    00082         if (!iv && !(IVRequirement() == INTERNALLY_GENERATED_IV || IVRequirement() == UNIQUE_IV || !IsResynchronizable()))
    00083                 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV");
    00084 }
    00085
    00086 const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs &params)
    00087 {
    00088         const byte *iv;
    00089         if (params.GetValue(Name::IV(), iv))
    00090                 ThrowIfInvalidIV(iv);
    00091         else
    00092                 ThrowIfResynchronizable();
    00093         return iv;
    00094 }
    00095
    00096 void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV)
    00097 {
    00098         rng.GenerateBlock(IV, IVSize());
    00099 }
    00100
    00101 void BlockTransformation::ProcessAndXorMultipleBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t numberOfBlocks) const
    00102 {
    00103         unsigned int blockSize = BlockSize();
    00104         while (numberOfBlocks--)
    00105         {
    00106                 ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
    00107                 inBlocks += blockSize;
    00108                 outBlocks += blockSize;
    00109                 if (xorBlocks)
    00110                         xorBlocks += blockSize;
    00111         }
    00112 }
    00113
    00114 unsigned int BlockTransformation::BlockAlignment() const
    00115 {
    00116         return GetAlignmentOf<word32>();
    00117 }
    00118
    00119 void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
    00120 {
    00121         assert(MinLastBlockSize() == 0);        // this function should be overriden otherwise
    00122
    00123         if (length == MandatoryBlockSize())
    00124                 ProcessData(outString, inString, length);
    00125         else if (length != 0)
    00126                 throw NotImplemented("StreamTransformation: this object does't support a special last block");
    00127 }
    00128
    00129 unsigned int RandomNumberGenerator::GenerateBit()
    00130 {
    00131         return GenerateByte() & 1;
    00132 }
    00133
    00134 byte RandomNumberGenerator::GenerateByte()
    00135 {
    00136         byte b;
    00137         GenerateBlock(&b, 1);
    00138         return b;
    00139 }
    00140
    00141 word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
    00142 {
    00143         word32 range = max-min;
    00144         const int maxBits = BitPrecision(range);
    00145
    00146         word32 value;
    00147
    00148         do
    00149         {
    00150                 GenerateBlock((byte *)&value, sizeof(value));
    00151                 value = Crop(value, maxBits);
    00152         } while (value > range);
    00153
    00154         return value+min;
    00155 }
    00156
    00157 void RandomNumberGenerator::GenerateBlock(byte *output, size_t size)
    00158 {
    00159         ArraySink s(output, size);
    00160         GenerateIntoBufferedTransformation(s, BufferedTransformation::NULL_CHANNEL, size);
    00161 }
    00162
    00163 void RandomNumberGenerator::DiscardBytes(size_t n)
    00164 {
    00165         GenerateIntoBufferedTransformation(TheBitBucket(), BufferedTransformation::NULL_CHANNEL, n);
    00166 }
    00167
    00168 void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
    00169 {
    00170         FixedSizeSecBlock<byte, 256> buffer;
    00171         while (length)
    00172         {
    00173                 size_t len = UnsignedMin(buffer.size(), length);
    00174                 GenerateBlock(buffer, len);
    00175                 target.ChannelPut(channel, buffer, len);
    00176                 length -= len;
    00177         }
    00178 }
    00179
    00180 //! see NullRNG()
    00181 class ClassNullRNG : public RandomNumberGenerator
    00182 {
    00183 public:
    00184         std::string AlgorithmName() const {return "NullRNG";}
    00185         void GenerateBlock(byte *output, size_t size) {throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");}
    00186 };
    00187
    00188 RandomNumberGenerator & NullRNG()
    00189 {
    00190         static ClassNullRNG s_nullRNG;
    00191         return s_nullRNG;
    00192 }
    00193
    00194 bool HashTransformation::TruncatedVerify(const byte *digestIn, size_t digestLength)
    00195 {
    00196         ThrowIfInvalidTruncatedSize(digestLength);
    00197         SecByteBlock digest(digestLength);
    00198         TruncatedFinal(digest, digestLength);
    00199         return memcmp(digest, digestIn, digestLength) == 0;
    00200 }
    00201
    00202 void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const
    00203 {
    00204         if (size > DigestSize())
    00205                 throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes");
    00206 }
    00207
    00208 unsigned int BufferedTransformation::GetMaxWaitObjectCount() const
    00209 {
    00210         const BufferedTransformation *t = AttachedTransformation();
    00211         return t ? t->GetMaxWaitObjectCount() : 0;
    00212 }
    00213
    00214 void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
    00215 {
    00216         BufferedTransformation *t = AttachedTransformation();
    00217         if (t)
    00218                 t->GetWaitObjects(container, callStack);  // reduce clutter by not adding to stack here
    00219 }
    00220
    00221 void BufferedTransformation::Initialize(const NameValuePairs &parameters, int propagation)
    00222 {
    00223         assert(!AttachedTransformation());
    00224         IsolatedInitialize(parameters);
    00225 }
    00226
    00227 bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking)
    00228 {
    00229         assert(!AttachedTransformation());
    00230         return IsolatedFlush(hardFlush, blocking);
    00231 }
    00232
    00233 bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking)
    00234 {
    00235         assert(!AttachedTransformation());
    00236         return IsolatedMessageSeriesEnd(blocking);
    00237 }
    00238
    00239 byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size)
    00240 {
    00241         if (channel.empty())
    00242                 return CreatePutSpace(size);
    00243         else
    00244                 throw NoChannelSupport();
    00245 }
    00246
    00247 size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
    00248 {
    00249         if (channel.empty())
    00250                 return Put2(begin, length, messageEnd, blocking);
    00251         else
    00252                 throw NoChannelSupport();
    00253 }
    00254
    00255 size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
    00256 {
    00257         if (channel.empty())
    00258                 return PutModifiable2(begin, length, messageEnd, blocking);
    00259         else
    00260                 return ChannelPut2(channel, begin, length, messageEnd, blocking);
    00261 }
    00262
    00263 bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
    00264 {
    00265         if (channel.empty())
    00266                 return Flush(completeFlush, propagation, blocking);
    00267         else
    00268                 throw NoChannelSupport();
    00269 }
    00270
    00271 bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
    00272 {
    00273         if (channel.empty())
    00274                 return MessageSeriesEnd(propagation, blocking);
    00275         else
    00276                 throw NoChannelSupport();
    00277 }
    00278
    00279 lword BufferedTransformation::MaxRetrievable() const
    00280 {
    00281         if (AttachedTransformation())
    00282                 return AttachedTransformation()->MaxRetrievable();
    00283         else
    00284                 return CopyTo(TheBitBucket());
    00285 }
    00286
    00287 bool BufferedTransformation::AnyRetrievable() const
    00288 {
    00289         if (AttachedTransformation())
    00290                 return AttachedTransformation()->AnyRetrievable();
    00291         else
    00292         {
    00293                 byte b;
    00294                 return Peek(b) != 0;
    00295         }
    00296 }
    00297
    00298 size_t BufferedTransformation::Get(byte &outByte)
    00299 {
    00300         if (AttachedTransformation())
    00301                 return AttachedTransformation()->Get(outByte);
    00302         else
    00303                 return Get(&outByte, 1);
    00304 }
    00305
    00306 size_t BufferedTransformation::Get(byte *outString, size_t getMax)
    00307 {
    00308         if (AttachedTransformation())
    00309                 return AttachedTransformation()->Get(outString, getMax);
    00310         else
    00311         {
    00312                 ArraySink arraySink(outString, getMax);
    00313                 return (size_t)TransferTo(arraySink, getMax);
    00314         }
    00315 }
    00316
    00317 size_t BufferedTransformation::Peek(byte &outByte) const
    00318 {
    00319         if (AttachedTransformation())
    00320                 return AttachedTransformation()->Peek(outByte);
    00321         else
    00322                 return Peek(&outByte, 1);
    00323 }
    00324
    00325 size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const
    00326 {
    00327         if (AttachedTransformation())
    00328                 return AttachedTransformation()->Peek(outString, peekMax);
    00329         else
    00330         {
    00331                 ArraySink arraySink(outString, peekMax);
    00332                 return (size_t)CopyTo(arraySink, peekMax);
    00333         }
    00334 }
    00335
    00336 lword BufferedTransformation::Skip(lword skipMax)
    00337 {
    00338         if (AttachedTransformation())
    00339                 return AttachedTransformation()->Skip(skipMax);
    00340         else
    00341                 return TransferTo(TheBitBucket(), skipMax);
    00342 }
    00343
    00344 lword BufferedTransformation::TotalBytesRetrievable() const
    00345 {
    00346         if (AttachedTransformation())
    00347                 return AttachedTransformation()->TotalBytesRetrievable();
    00348         else
    00349                 return MaxRetrievable();
    00350 }
    00351
    00352 unsigned int BufferedTransformation::NumberOfMessages() const
    00353 {
    00354         if (AttachedTransformation())
    00355                 return AttachedTransformation()->NumberOfMessages();
    00356         else
    00357                 return CopyMessagesTo(TheBitBucket());
    00358 }
    00359
    00360 bool BufferedTransformation::AnyMessages() const
    00361 {
    00362         if (AttachedTransformation())
    00363                 return AttachedTransformation()->AnyMessages();
    00364         else
    00365                 return NumberOfMessages() != 0;
    00366 }
    00367
    00368 bool BufferedTransformation::GetNextMessage()
    00369 {
    00370         if (AttachedTransformation())
    00371                 return AttachedTransformation()->GetNextMessage();
    00372         else
    00373         {
    00374                 assert(!AnyMessages());
    00375                 return false;
    00376         }
    00377 }
    00378
    00379 unsigned int BufferedTransformation::SkipMessages(unsigned int count)
    00380 {
    00381         if (AttachedTransformation())
    00382                 return AttachedTransformation()->SkipMessages(count);
    00383         else
    00384                 return TransferMessagesTo(TheBitBucket(), count);
    00385 }
    00386
    00387 size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking)
    00388 {
    00389         if (AttachedTransformation())
    00390                 return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking);
    00391         else
    00392         {
    00393                 unsigned int maxMessages = messageCount;
    00394                 for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++)
    00395                 {
    00396                         size_t blockedBytes;
    00397                         lword transferredBytes;
    00398
    00399                         while (AnyRetrievable())
    00400                         {
    00401                                 transferredBytes = LWORD_MAX;
    00402                                 blockedBytes = TransferTo2(target, transferredBytes, channel, blocking);
    00403                                 if (blockedBytes > 0)
    00404                                         return blockedBytes;
    00405                         }
    00406
    00407                         if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking))
    00408                                 return 1;
    00409
    00410                         bool result = GetNextMessage();
    00411                         assert(result);
    00412                 }
    00413                 return 0;
    00414         }
    00415 }
    00416
    00417 unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
    00418 {
    00419         if (AttachedTransformation())
    00420                 return AttachedTransformation()->CopyMessagesTo(target, count, channel);
    00421         else
    00422                 return 0;
    00423 }
    00424
    00425 void BufferedTransformation::SkipAll()
    00426 {
    00427         if (AttachedTransformation())
    00428                 AttachedTransformation()->SkipAll();
    00429         else
    00430         {
    00431                 while (SkipMessages()) {}
    00432                 while (Skip()) {}
    00433         }
    00434 }
    00435
    00436 size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking)
    00437 {
    00438         if (AttachedTransformation())
    00439                 return AttachedTransformation()->TransferAllTo2(target, channel, blocking);
    00440         else
    00441         {
    00442                 assert(!NumberOfMessageSeries());
    00443
    00444                 unsigned int messageCount;
    00445                 do
    00446                 {
    00447                         messageCount = UINT_MAX;
    00448                         size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking);
    00449                         if (blockedBytes)
    00450                                 return blockedBytes;
    00451                 }
    00452                 while (messageCount != 0);
    00453
    00454                 lword byteCount;
    00455                 do
    00456                 {
    00457                         byteCount = ULONG_MAX;
    00458                         size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking);
    00459                         if (blockedBytes)
    00460                                 return blockedBytes;
    00461                 }
    00462                 while (byteCount != 0);
    00463
    00464                 return 0;
    00465         }
    00466 }
    00467
    00468 void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const
    00469 {
    00470         if (AttachedTransformation())
    00471                 AttachedTransformation()->CopyAllTo(target, channel);
    00472         else
    00473         {
    00474                 assert(!NumberOfMessageSeries());
    00475                 while (CopyMessagesTo(target, UINT_MAX, channel)) {}
    00476         }
    00477 }
    00478
    00479 void BufferedTransformation::SetRetrievalChannel(const std::string &channel)
    00480 {
    00481         if (AttachedTransformation())
    00482                 AttachedTransformation()->SetRetrievalChannel(channel);
    00483 }
    00484
    00485 size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking)
    00486 {
    00487         PutWord(false, order, m_buf, value);
    00488         return ChannelPut(channel, m_buf, 2, blocking);
    00489 }
    00490
    00491 size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking)
    00492 {
    00493         PutWord(false, order, m_buf, value);
    00494         return ChannelPut(channel, m_buf, 4, blocking);
    00495 }
    00496
    00497 size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
    00498 {
    00499         return ChannelPutWord16(NULL_CHANNEL, value, order, blocking);
    00500 }
    00501
    00502 size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking)
    00503 {
    00504         return ChannelPutWord32(NULL_CHANNEL, value, order, blocking);
    00505 }
    00506
    00507 size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const
    00508 {
    00509         byte buf[2] = {0, 0};
    00510         size_t len = Peek(buf, 2);
    00511
    00512         if (order)
    00513                 value = (buf[0] << 8) | buf[1];
    00514         else
    00515                 value = (buf[1] << 8) | buf[0];
    00516
    00517         return len;
    00518 }
    00519
    00520 size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const
    00521 {
    00522         byte buf[4] = {0, 0, 0, 0};
    00523         size_t len = Peek(buf, 4);
    00524
    00525         if (order)
    00526                 value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
    00527         else
    00528                 value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
    00529
    00530         return len;
    00531 }
    00532
    00533 size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
    00534 {
    00535         return (size_t)Skip(PeekWord16(value, order));
    00536 }
    00537
    00538 size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
    00539 {
    00540         return (size_t)Skip(PeekWord32(value, order));
    00541 }
    00542
    00543 void BufferedTransformation::Attach(BufferedTransformation *newOut)
    00544 {
    00545         if (AttachedTransformation() && AttachedTransformation()->Attachable())
    00546                 AttachedTransformation()->Attach(newOut);
    00547         else
    00548                 Detach(newOut);
    00549 }
    00550
    00551 void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
    00552 {
    00553         GenerateRandom(rng, MakeParameters("KeySize", (int)keySize));
    00554 }
    00555
    00556 class PK_DefaultEncryptionFilter : public Unflushable<Filter>
    00557 {
    00558 public:
    00559         PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
    00560                 : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters)
    00561         {
    00562                 Detach(attachment);
    00563         }
    00564
    00565         size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
    00566         {
    00567                 FILTER_BEGIN;
    00568                 m_plaintextQueue.Put(inString, length);
    00569
    00570                 if (messageEnd)
    00571                 {
    00572                         {
    00573                         size_t plaintextLength;
    00574                         if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength))
    00575                                 throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long");
    00576                         size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
    00577
    00578                         SecByteBlock plaintext(plaintextLength);
    00579                         m_plaintextQueue.Get(plaintext, plaintextLength);
    00580                         m_ciphertext.resize(ciphertextLength);
    00581                         m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters);
    00582                         }
    00583
    00584                         FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd);
    00585                 }
    00586                 FILTER_END_NO_MESSAGE_END;
    00587         }
    00588
    00589         RandomNumberGenerator &m_rng;
    00590         const PK_Encryptor &m_encryptor;
    00591         const NameValuePairs &m_parameters;
    00592         ByteQueue m_plaintextQueue;
    00593         SecByteBlock m_ciphertext;
    00594 };
    00595
    00596 BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs &parameters) const
    00597 {
    00598         return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters);
    00599 }
    00600
    00601 class PK_DefaultDecryptionFilter : public Unflushable<Filter>
    00602 {
    00603 public:
    00604         PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
    00605                 : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters)
    00606         {
    00607                 Detach(attachment);
    00608         }
    00609
    00610         size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
    00611         {
    00612                 FILTER_BEGIN;
    00613                 m_ciphertextQueue.Put(inString, length);
    00614
    00615                 if (messageEnd)
    00616                 {
    00617                         {
    00618                         size_t ciphertextLength;
    00619                         if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength))
    00620                                 throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long");
    00621                         size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength);
    00622
    00623                         SecByteBlock ciphertext(ciphertextLength);
    00624                         m_ciphertextQueue.Get(ciphertext, ciphertextLength);
    00625                         m_plaintext.resize(maxPlaintextLength);
    00626                         m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters);
    00627                         if (!m_result.isValidCoding)
    00628                                 throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext");
    00629                         }
    00630
    00631                         FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd);
    00632                 }
    00633                 FILTER_END_NO_MESSAGE_END;
    00634         }
    00635
    00636         RandomNumberGenerator &m_rng;
    00637         const PK_Decryptor &m_decryptor;
    00638         const NameValuePairs &m_parameters;
    00639         ByteQueue m_ciphertextQueue;
    00640         SecByteBlock m_plaintext;
    00641         DecodingResult m_result;
    00642 };
    00643
    00644 BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs &parameters) const
    00645 {
    00646         return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters);
    00647 }
    00648
    00649 size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
    00650 {
    00651         std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
    00652         return SignAndRestart(rng, *m, signature, false);
    00653 }
    00654
    00655 size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const
    00656 {
    00657         std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
    00658         m->Update(message, messageLen);
    00659         return SignAndRestart(rng, *m, signature, false);
    00660 }
    00661
    00662 size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength,
    00663         const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const
    00664 {
    00665         std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
    00666         InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength);
    00667         m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
    00668         return SignAndRestart(rng, *m, signature, false);
    00669 }
    00670
    00671 bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const
    00672 {
    00673         std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
    00674         return VerifyAndRestart(*m);
    00675 }
    00676
    00677 bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLength) const
    00678 {
    00679         std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
    00680         InputSignature(*m, signature, signatureLength);
    00681         m->Update(message, messageLen);
    00682         return VerifyAndRestart(*m);
    00683 }
    00684
    00685 DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const
    00686 {
    00687         std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
    00688         return RecoverAndRestart(recoveredMessage, *m);
    00689 }
    00690
    00691 DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage,
    00692         const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength,
    00693         const byte *signature, size_t signatureLength) const
    00694 {
    00695         std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
    00696         InputSignature(*m, signature, signatureLength);
    00697         m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
    00698         return RecoverAndRestart(recoveredMessage, *m);
    00699 }
    00700
    00701 void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
    00702 {
    00703         GeneratePrivateKey(rng, privateKey);
    00704         GeneratePublicKey(rng, privateKey, publicKey);
    00705 }
    00706
    00707 void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
    00708 {
    00709         GenerateStaticPrivateKey(rng, privateKey);
    00710         GenerateStaticPublicKey(rng, privateKey, publicKey);
    00711 }
    00712
    00713 void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
    00714 {
    00715         GenerateEphemeralPrivateKey(rng, privateKey);
    00716         GenerateEphemeralPublicKey(rng, privateKey, publicKey);
    00717 }
    00718
    00719 NAMESPACE_END
    00720
    00721 #endif