00001
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 ¶ms)
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 ¶ms)
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);
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
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);
00193 }
00194
00195 void BufferedTransformation::Initialize(const NameValuePairs ¶meters, 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 ¶meters)
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 ¶meters) 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 ¶meters)
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 ¶meters) 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