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