00001
00002
00003 #include "pch.h"
00004 #include "config.h"
00005
00006 #if CRYPTOPP_MSC_VERSION
00007 # pragma warning(disable: 4127 4189 4459)
00008 #endif
00009
00010 #if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
00011 # pragma GCC diagnostic ignored "-Wunused-value"
00012 # pragma GCC diagnostic ignored "-Wunused-variable"
00013 # pragma GCC diagnostic ignored "-Wunused-parameter"
00014 #endif
00015
00016 #ifndef CRYPTOPP_IMPORTS
00017
00018 #include "cryptlib.h"
00019 #include "misc.h"
00020 #include "filters.h"
00021 #include "algparam.h"
00022 #include "fips140.h"
00023 #include "argnames.h"
00024 #include "fltrimpl.h"
00025 #include "trdlocal.h"
00026 #include "osrng.h"
00027 #include "secblock.h"
00028 #include "smartptr.h"
00029
00030
00031 #if (defined(__CYGWIN__) || defined(__CYGWIN32__)) && defined(PREFER_WINDOWS_STYLE_SOCKETS)
00032 # error Cygwin does not support Windows style sockets. See http://www.cygwin.com/faq.html#faq.api.winsock
00033 #endif
00034
00035
00036 #define HAVE_GCC_INIT_PRIORITY (__GNUC__ && (CRYPTOPP_INIT_PRIORITY > 0) && !(MACPORTS_GCC_COMPILER > 0))
00037 #define HAVE_MSC_INIT_PRIORITY (_MSC_VER && (CRYPTOPP_INIT_PRIORITY > 0))
00038
00039 NAMESPACE_BEGIN(CryptoPP)
00040
00041 CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1);
00042 CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2);
00043 CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4);
00044 CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8);
00045 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
00046 CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word));
00047 #endif
00048
00049 #if HAVE_GCC_INIT_PRIORITY
00050 CRYPTOPP_COMPILE_ASSERT(CRYPTOPP_INIT_PRIORITY >= 101);
00051 const std::string DEFAULT_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 25)));
00052 const std::string AAD_CHANNEL __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 26))) = "AAD";
00053 const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
00054 #elif HAVE_MSC_INIT_PRIORITY
00055 #pragma warning(disable: 4073)
00056 #pragma init_seg(lib)
00057 const std::string DEFAULT_CHANNEL;
00058 const std::string AAD_CHANNEL = "AAD";
00059 const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
00060 #pragma warning(default: 4073)
00061 #else
00062 const std::string DEFAULT_CHANNEL;
00063 const std::string AAD_CHANNEL = "AAD";
00064 const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
00065 #endif
00066
00067 class NullNameValuePairs : public NameValuePairs
00068 {
00069 public:
00070 bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
00071 {CRYPTOPP_UNUSED(name); CRYPTOPP_UNUSED(valueType); CRYPTOPP_UNUSED(pValue); return false;}
00072 };
00073
00074 #if HAVE_GCC_INIT_PRIORITY
00075 const simple_ptr<NullNameValuePairs> s_pNullNameValuePairs __attribute__ ((init_priority (CRYPTOPP_INIT_PRIORITY + 30))) = new NullNameValuePairs;
00076 const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p;
00077 #else
00078 const simple_ptr<NullNameValuePairs> s_pNullNameValuePairs(new NullNameValuePairs);
00079 const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p;
00080 #endif
00081
00082 BufferedTransformation & TheBitBucket()
00083 {
00084 static BitBucket bitBucket;
00085 return bitBucket;
00086 }
00087
00088 Algorithm::Algorithm(bool checkSelfTestStatus)
00089 {
00090 if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled())
00091 {
00092 if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread())
00093 throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed.");
00094
00095 if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED)
00096 throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed.");
00097 }
00098 }
00099
00100 void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs ¶ms)
00101 {
00102 this->ThrowIfInvalidKeyLength(length);
00103 this->UncheckedSetKey(key, (unsigned int)length, params);
00104 }
00105
00106 void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds)
00107 {
00108 SetKey(key, length, MakeParameters(Name::Rounds(), rounds));
00109 }
00110
00111 void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)
00112 {
00113 SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength)));
00114 }
00115
00116 void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length)
00117 {
00118 if (!IsValidKeyLength(length))
00119 throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length);
00120 }
00121
00122 void SimpleKeyingInterface::ThrowIfResynchronizable()
00123 {
00124 if (IsResynchronizable())
00125 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV");
00126 }
00127
00128 void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv)
00129 {
00130 if (!iv && IVRequirement() == UNPREDICTABLE_RANDOM_IV)
00131 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV");
00132 }
00133
00134 size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int size)
00135 {
00136 if (size < 0)
00137 return IVSize();
00138 else if ((size_t)size < MinIVLength())
00139 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " is less than the minimum of " + IntToString(MinIVLength()));
00140 else if ((size_t)size > MaxIVLength())
00141 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " exceeds the maximum of " + IntToString(MaxIVLength()));
00142 else
00143 return size;
00144 }
00145
00146 const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size)
00147 {
00148 ConstByteArrayParameter ivWithLength;
00149 const byte *iv;
00150 bool found = false;
00151
00152 try {found = params.GetValue(Name::IV(), ivWithLength);}
00153 catch (const NameValuePairs::ValueTypeMismatch &) {}
00154
00155 if (found)
00156 {
00157 iv = ivWithLength.begin();
00158 ThrowIfInvalidIV(iv);
00159 size = ThrowIfInvalidIVLength((int)ivWithLength.size());
00160 return iv;
00161 }
00162 else if (params.GetValue(Name::IV(), iv))
00163 {
00164 ThrowIfInvalidIV(iv);
00165 size = IVSize();
00166 return iv;
00167 }
00168 else
00169 {
00170 ThrowIfResynchronizable();
00171 size = 0;
00172 return NULL;
00173 }
00174 }
00175
00176 void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV)
00177 {
00178 rng.GenerateBlock(IV, IVSize());
00179 }
00180
00181 size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
00182 {
00183 assert(inBlocks);
00184 assert(outBlocks);
00185 assert(length);
00186
00187 size_t blockSize = BlockSize();
00188 size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize;
00189 size_t xorIncrement = xorBlocks ? blockSize : 0;
00190 size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize;
00191
00192 if (flags & BT_ReverseDirection)
00193 {
00194 assert(length % blockSize == 0);
00195 inBlocks += length - blockSize;
00196 xorBlocks += length - blockSize;
00197 outBlocks += length - blockSize;
00198 inIncrement = 0-inIncrement;
00199 xorIncrement = 0-xorIncrement;
00200 outIncrement = 0-outIncrement;
00201 }
00202
00203 while (length >= blockSize)
00204 {
00205 if (flags & BT_XorInput)
00206 {
00207
00208 assert(xorBlocks);
00209 #if defined(__COVERITY__)
00210 if (xorBlocks)
00211 #endif
00212 xorbuf(outBlocks, xorBlocks, inBlocks, blockSize);
00213 ProcessBlock(outBlocks);
00214 }
00215 else
00216 {
00217
00218 ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
00219 }
00220
00221 if (flags & BT_InBlockIsCounter)
00222 const_cast<byte *>(inBlocks)[blockSize-1]++;
00223 inBlocks += inIncrement;
00224 outBlocks += outIncrement;
00225 xorBlocks += xorIncrement;
00226 length -= blockSize;
00227 }
00228
00229 return length;
00230 }
00231
00232 unsigned int BlockTransformation::OptimalDataAlignment() const
00233 {
00234 return GetAlignmentOf<word32>();
00235 }
00236
00237 unsigned int StreamTransformation::OptimalDataAlignment() const
00238 {
00239 return GetAlignmentOf<word32>();
00240 }
00241
00242 unsigned int HashTransformation::OptimalDataAlignment() const
00243 {
00244 return GetAlignmentOf<word32>();
00245 }
00246
00247 void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
00248 {
00249 assert(MinLastBlockSize() == 0);
00250
00251 if (length == MandatoryBlockSize())
00252 ProcessData(outString, inString, length);
00253 else if (length != 0)
00254 throw NotImplemented(AlgorithmName() + ": this object does't support a special last block");
00255 }
00256
00257 void AuthenticatedSymmetricCipher::SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength)
00258 {
00259 if (headerLength > MaxHeaderLength())
00260 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": header length " + IntToString(headerLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
00261
00262 if (messageLength > MaxMessageLength())
00263 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": message length " + IntToString(messageLength) + " exceeds the maximum of " + IntToString(MaxMessageLength()));
00264
00265 if (footerLength > MaxFooterLength())
00266 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": footer length " + IntToString(footerLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
00267
00268 UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength);
00269 }
00270
00271 void AuthenticatedSymmetricCipher::EncryptAndAuthenticate(byte *ciphertext, byte *mac, size_t macSize, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *message, size_t messageLength)
00272 {
00273 Resynchronize(iv, ivLength);
00274 SpecifyDataLengths(headerLength, messageLength);
00275 Update(header, headerLength);
00276 ProcessString(ciphertext, message, messageLength);
00277 TruncatedFinal(mac, macSize);
00278 }
00279
00280 bool AuthenticatedSymmetricCipher::DecryptAndVerify(byte *message, const byte *mac, size_t macLength, const byte *iv, int ivLength, const byte *header, size_t headerLength, const byte *ciphertext, size_t ciphertextLength)
00281 {
00282 Resynchronize(iv, ivLength);
00283 SpecifyDataLengths(headerLength, ciphertextLength);
00284 Update(header, headerLength);
00285 ProcessString(message, ciphertext, ciphertextLength);
00286 return TruncatedVerify(mac, macLength);
00287 }
00288
00289 unsigned int RandomNumberGenerator::GenerateBit()
00290 {
00291 return GenerateByte() & 1;
00292 }
00293
00294 byte RandomNumberGenerator::GenerateByte()
00295 {
00296 byte b;
00297 GenerateBlock(&b, 1);
00298 return b;
00299 }
00300
00301 word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
00302 {
00303 const word32 range = max-min;
00304 const int maxBits = BitPrecision(range);
00305
00306 word32 value;
00307
00308 do
00309 {
00310 GenerateBlock((byte *)&value, sizeof(value));
00311 value = Crop(value, maxBits);
00312 } while (value > range);
00313
00314 return value+min;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329 void RandomNumberGenerator::GenerateBlock(byte *output, size_t size)
00330 {
00331 CRYPTOPP_UNUSED(output), CRYPTOPP_UNUSED(size);
00332
00333 #if 0
00334
00335 throw NotImplemented("RandomNumberGenerator: GenerateBlock not implemented");
00336 #endif
00337
00338 ArraySink s(output, size);
00339 GenerateIntoBufferedTransformation(s, DEFAULT_CHANNEL, size);
00340 }
00341
00342 void RandomNumberGenerator::DiscardBytes(size_t n)
00343 {
00344 GenerateIntoBufferedTransformation(TheBitBucket(), DEFAULT_CHANNEL, n);
00345 }
00346
00347 void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
00348 {
00349 FixedSizeSecBlock<byte, 256> buffer;
00350 while (length)
00351 {
00352 size_t len = UnsignedMin(buffer.size(), length);
00353 GenerateBlock(buffer, len);
00354 size_t rem = target.ChannelPut(channel, buffer, len);
00355 CRYPTOPP_UNUSED(rem); assert(rem == 0);
00356 length -= len;
00357 }
00358 }
00359
00360
00361
00362
00363
00364
00365 class ClassNullRNG : public RandomNumberGenerator
00366 {
00367 public:
00368
00369
00370 std::string AlgorithmName() const {return "NullRNG";}
00371
00372 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
00373
00374 byte GenerateByte () {}
00375
00376 unsigned int GenerateBit () {}
00377
00378 word32 GenerateWord32 (word32 min, word32 max) {}
00379 #endif
00380
00381
00382 void GenerateBlock(byte *output, size_t size)
00383 {
00384 CRYPTOPP_UNUSED(output); CRYPTOPP_UNUSED(size);
00385 throw NotImplemented("NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes");
00386 }
00387
00388 #if defined(CRYPTOPP_DOXYGEN_PROCESSING)
00389
00390 void GenerateIntoBufferedTransformation (BufferedTransformation &target, const std::string &channel, lword length) {}
00391
00392 void IncorporateEntropy (const byte *input, size_t length) {}
00393
00394 bool CanIncorporateEntropy () const {}
00395
00396 void DiscardBytes (size_t n) {}
00397
00398 void Shuffle (IT begin, IT end) {}
00399
00400 private:
00401 Clonable* Clone () const { return NULL; }
00402 #endif
00403 };
00404
00405 RandomNumberGenerator & NullRNG()
00406 {
00407 static ClassNullRNG s_nullRNG;
00408 return s_nullRNG;
00409 }
00410
00411 bool HashTransformation::TruncatedVerify(const byte *digestIn, size_t digestLength)
00412 {
00413 ThrowIfInvalidTruncatedSize(digestLength);
00414 SecByteBlock digest(digestLength);
00415 TruncatedFinal(digest, digestLength);
00416 return VerifyBufsEqual(digest, digestIn, digestLength);
00417 }
00418
00419 void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const
00420 {
00421 if (size > DigestSize())
00422 throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes");
00423 }
00424
00425 unsigned int BufferedTransformation::GetMaxWaitObjectCount() const
00426 {
00427 const BufferedTransformation *t = AttachedTransformation();
00428 return t ? t->GetMaxWaitObjectCount() : 0;
00429 }
00430
00431 void BufferedTransformation::GetWaitObjects(WaitObjectContainer &container, CallStack const& callStack)
00432 {
00433 BufferedTransformation *t = AttachedTransformation();
00434 if (t)
00435 t->GetWaitObjects(container, callStack);
00436 }
00437
00438 void BufferedTransformation::Initialize(const NameValuePairs ¶meters, int propagation)
00439 {
00440 CRYPTOPP_UNUSED(propagation);
00441 assert(!AttachedTransformation());
00442 IsolatedInitialize(parameters);
00443 }
00444
00445 bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking)
00446 {
00447 CRYPTOPP_UNUSED(propagation);
00448 assert(!AttachedTransformation());
00449 return IsolatedFlush(hardFlush, blocking);
00450 }
00451
00452 bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking)
00453 {
00454 CRYPTOPP_UNUSED(propagation);
00455 assert(!AttachedTransformation());
00456 return IsolatedMessageSeriesEnd(blocking);
00457 }
00458
00459 byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size)
00460 {
00461 if (channel.empty())
00462 return CreatePutSpace(size);
00463 else
00464 throw NoChannelSupport(AlgorithmName());
00465 }
00466
00467 size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
00468 {
00469 if (channel.empty())
00470 return Put2(begin, length, messageEnd, blocking);
00471 else
00472 throw NoChannelSupport(AlgorithmName());
00473 }
00474
00475 size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
00476 {
00477 if (channel.empty())
00478 return PutModifiable2(begin, length, messageEnd, blocking);
00479 else
00480 return ChannelPut2(channel, begin, length, messageEnd, blocking);
00481 }
00482
00483 bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
00484 {
00485 if (channel.empty())
00486 return Flush(completeFlush, propagation, blocking);
00487 else
00488 throw NoChannelSupport(AlgorithmName());
00489 }
00490
00491 bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
00492 {
00493 if (channel.empty())
00494 return MessageSeriesEnd(propagation, blocking);
00495 else
00496 throw NoChannelSupport(AlgorithmName());
00497 }
00498
00499 lword BufferedTransformation::MaxRetrievable() const
00500 {
00501 if (AttachedTransformation())
00502 return AttachedTransformation()->MaxRetrievable();
00503 else
00504 return CopyTo(TheBitBucket());
00505 }
00506
00507 bool BufferedTransformation::AnyRetrievable() const
00508 {
00509 if (AttachedTransformation())
00510 return AttachedTransformation()->AnyRetrievable();
00511 else
00512 {
00513 byte b;
00514 return Peek(b) != 0;
00515 }
00516 }
00517
00518 size_t BufferedTransformation::Get(byte &outByte)
00519 {
00520 if (AttachedTransformation())
00521 return AttachedTransformation()->Get(outByte);
00522 else
00523 return Get(&outByte, 1);
00524 }
00525
00526 size_t BufferedTransformation::Get(byte *outString, size_t getMax)
00527 {
00528 if (AttachedTransformation())
00529 return AttachedTransformation()->Get(outString, getMax);
00530 else
00531 {
00532 ArraySink arraySink(outString, getMax);
00533 return (size_t)TransferTo(arraySink, getMax);
00534 }
00535 }
00536
00537 size_t BufferedTransformation::Peek(byte &outByte) const
00538 {
00539 if (AttachedTransformation())
00540 return AttachedTransformation()->Peek(outByte);
00541 else
00542 return Peek(&outByte, 1);
00543 }
00544
00545 size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const
00546 {
00547 if (AttachedTransformation())
00548 return AttachedTransformation()->Peek(outString, peekMax);
00549 else
00550 {
00551 ArraySink arraySink(outString, peekMax);
00552 return (size_t)CopyTo(arraySink, peekMax);
00553 }
00554 }
00555
00556 lword BufferedTransformation::Skip(lword skipMax)
00557 {
00558 if (AttachedTransformation())
00559 return AttachedTransformation()->Skip(skipMax);
00560 else
00561 return TransferTo(TheBitBucket(), skipMax);
00562 }
00563
00564 lword BufferedTransformation::TotalBytesRetrievable() const
00565 {
00566 if (AttachedTransformation())
00567 return AttachedTransformation()->TotalBytesRetrievable();
00568 else
00569 return MaxRetrievable();
00570 }
00571
00572 unsigned int BufferedTransformation::NumberOfMessages() const
00573 {
00574 if (AttachedTransformation())
00575 return AttachedTransformation()->NumberOfMessages();
00576 else
00577 return CopyMessagesTo(TheBitBucket());
00578 }
00579
00580 bool BufferedTransformation::AnyMessages() const
00581 {
00582 if (AttachedTransformation())
00583 return AttachedTransformation()->AnyMessages();
00584 else
00585 return NumberOfMessages() != 0;
00586 }
00587
00588 bool BufferedTransformation::GetNextMessage()
00589 {
00590 if (AttachedTransformation())
00591 return AttachedTransformation()->GetNextMessage();
00592 else
00593 {
00594 assert(!AnyMessages());
00595 return false;
00596 }
00597 }
00598
00599 unsigned int BufferedTransformation::SkipMessages(unsigned int count)
00600 {
00601 if (AttachedTransformation())
00602 return AttachedTransformation()->SkipMessages(count);
00603 else
00604 return TransferMessagesTo(TheBitBucket(), count);
00605 }
00606
00607 size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking)
00608 {
00609 if (AttachedTransformation())
00610 return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking);
00611 else
00612 {
00613 unsigned int maxMessages = messageCount;
00614 for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++)
00615 {
00616 size_t blockedBytes;
00617 lword transferredBytes;
00618
00619 while (AnyRetrievable())
00620 {
00621 transferredBytes = LWORD_MAX;
00622 blockedBytes = TransferTo2(target, transferredBytes, channel, blocking);
00623 if (blockedBytes > 0)
00624 return blockedBytes;
00625 }
00626
00627 if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking))
00628 return 1;
00629
00630 bool result = GetNextMessage();
00631 CRYPTOPP_UNUSED(result); assert(result);
00632 }
00633 return 0;
00634 }
00635 }
00636
00637 unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
00638 {
00639 if (AttachedTransformation())
00640 return AttachedTransformation()->CopyMessagesTo(target, count, channel);
00641 else
00642 return 0;
00643 }
00644
00645 void BufferedTransformation::SkipAll()
00646 {
00647 if (AttachedTransformation())
00648 AttachedTransformation()->SkipAll();
00649 else
00650 {
00651 while (SkipMessages()) {}
00652 while (Skip()) {}
00653 }
00654 }
00655
00656 size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking)
00657 {
00658 if (AttachedTransformation())
00659 return AttachedTransformation()->TransferAllTo2(target, channel, blocking);
00660 else
00661 {
00662 assert(!NumberOfMessageSeries());
00663
00664 unsigned int messageCount;
00665 do
00666 {
00667 messageCount = UINT_MAX;
00668 size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking);
00669 if (blockedBytes)
00670 return blockedBytes;
00671 }
00672 while (messageCount != 0);
00673
00674 lword byteCount;
00675 do
00676 {
00677 byteCount = ULONG_MAX;
00678 size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking);
00679 if (blockedBytes)
00680 return blockedBytes;
00681 }
00682 while (byteCount != 0);
00683
00684 return 0;
00685 }
00686 }
00687
00688 void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const
00689 {
00690 if (AttachedTransformation())
00691 AttachedTransformation()->CopyAllTo(target, channel);
00692 else
00693 {
00694 assert(!NumberOfMessageSeries());
00695 while (CopyMessagesTo(target, UINT_MAX, channel)) {}
00696 }
00697 }
00698
00699 void BufferedTransformation::SetRetrievalChannel(const std::string &channel)
00700 {
00701 if (AttachedTransformation())
00702 AttachedTransformation()->SetRetrievalChannel(channel);
00703 }
00704
00705 size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking)
00706 {
00707 PutWord(false, order, m_buf, value);
00708 return ChannelPut(channel, m_buf, 2, blocking);
00709 }
00710
00711 size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking)
00712 {
00713 PutWord(false, order, m_buf, value);
00714 return ChannelPut(channel, m_buf, 4, blocking);
00715 }
00716
00717 size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
00718 {
00719 return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking);
00720 }
00721
00722 size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking)
00723 {
00724 return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking);
00725 }
00726
00727 size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const
00728 {
00729 byte buf[2] = {0, 0};
00730 size_t len = Peek(buf, 2);
00731
00732 if (order)
00733 value = (buf[0] << 8) | buf[1];
00734 else
00735 value = (buf[1] << 8) | buf[0];
00736
00737 return len;
00738 }
00739
00740 size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const
00741 {
00742 byte buf[4] = {0, 0, 0, 0};
00743 size_t len = Peek(buf, 4);
00744
00745 if (order)
00746 value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
00747 else
00748 value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
00749
00750 return len;
00751 }
00752
00753 size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
00754 {
00755 return (size_t)Skip(PeekWord16(value, order));
00756 }
00757
00758 size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
00759 {
00760 return (size_t)Skip(PeekWord32(value, order));
00761 }
00762
00763 void BufferedTransformation::Attach(BufferedTransformation *newOut)
00764 {
00765 if (AttachedTransformation() && AttachedTransformation()->Attachable())
00766 AttachedTransformation()->Attach(newOut);
00767 else
00768 Detach(newOut);
00769 }
00770
00771 void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
00772 {
00773 GenerateRandom(rng, MakeParameters("KeySize", (int)keySize));
00774 }
00775
00776 class PK_DefaultEncryptionFilter : public Unflushable<Filter>
00777 {
00778 public:
00779 PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters)
00780 : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters)
00781 {
00782 Detach(attachment);
00783 }
00784
00785 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00786 {
00787 FILTER_BEGIN;
00788 m_plaintextQueue.Put(inString, length);
00789
00790 if (messageEnd)
00791 {
00792 {
00793 size_t plaintextLength;
00794 if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength))
00795 throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long");
00796 size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
00797
00798 SecByteBlock plaintext(plaintextLength);
00799 m_plaintextQueue.Get(plaintext, plaintextLength);
00800 m_ciphertext.resize(ciphertextLength);
00801 m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters);
00802 }
00803
00804 FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd);
00805 }
00806 FILTER_END_NO_MESSAGE_END;
00807 }
00808
00809 RandomNumberGenerator &m_rng;
00810 const PK_Encryptor &m_encryptor;
00811 const NameValuePairs &m_parameters;
00812 ByteQueue m_plaintextQueue;
00813 SecByteBlock m_ciphertext;
00814 };
00815
00816 BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const
00817 {
00818 return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters);
00819 }
00820
00821 class PK_DefaultDecryptionFilter : public Unflushable<Filter>
00822 {
00823 public:
00824 PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters)
00825 : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters)
00826 {
00827 Detach(attachment);
00828 }
00829
00830 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
00831 {
00832 FILTER_BEGIN;
00833 m_ciphertextQueue.Put(inString, length);
00834
00835 if (messageEnd)
00836 {
00837 {
00838 size_t ciphertextLength;
00839 if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength))
00840 throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long");
00841 size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength);
00842
00843 SecByteBlock ciphertext(ciphertextLength);
00844 m_ciphertextQueue.Get(ciphertext, ciphertextLength);
00845 m_plaintext.resize(maxPlaintextLength);
00846 m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters);
00847 if (!m_result.isValidCoding)
00848 throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext");
00849 }
00850
00851 FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd);
00852 }
00853 FILTER_END_NO_MESSAGE_END;
00854 }
00855
00856 RandomNumberGenerator &m_rng;
00857 const PK_Decryptor &m_decryptor;
00858 const NameValuePairs &m_parameters;
00859 ByteQueue m_ciphertextQueue;
00860 SecByteBlock m_plaintext;
00861 DecodingResult m_result;
00862 };
00863
00864 BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const
00865 {
00866 return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters);
00867 }
00868
00869 size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
00870 {
00871 member_ptr<PK_MessageAccumulator> m(messageAccumulator);
00872 return SignAndRestart(rng, *m, signature, false);
00873 }
00874
00875 size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const
00876 {
00877 member_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
00878 m->Update(message, messageLen);
00879 return SignAndRestart(rng, *m, signature, false);
00880 }
00881
00882 size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength,
00883 const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const
00884 {
00885 member_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
00886 InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength);
00887 m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
00888 return SignAndRestart(rng, *m, signature, false);
00889 }
00890
00891 bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const
00892 {
00893 member_ptr<PK_MessageAccumulator> m(messageAccumulator);
00894 return VerifyAndRestart(*m);
00895 }
00896
00897 bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLength) const
00898 {
00899 member_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
00900 InputSignature(*m, signature, signatureLength);
00901 m->Update(message, messageLen);
00902 return VerifyAndRestart(*m);
00903 }
00904
00905 DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const
00906 {
00907 member_ptr<PK_MessageAccumulator> m(messageAccumulator);
00908 return RecoverAndRestart(recoveredMessage, *m);
00909 }
00910
00911 DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage,
00912 const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength,
00913 const byte *signature, size_t signatureLength) const
00914 {
00915 member_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
00916 InputSignature(*m, signature, signatureLength);
00917 m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
00918 return RecoverAndRestart(recoveredMessage, *m);
00919 }
00920
00921 void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
00922 {
00923 GeneratePrivateKey(rng, privateKey);
00924 GeneratePublicKey(rng, privateKey, publicKey);
00925 }
00926
00927 void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
00928 {
00929 GenerateStaticPrivateKey(rng, privateKey);
00930 GenerateStaticPublicKey(rng, privateKey, publicKey);
00931 }
00932
00933 void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
00934 {
00935 GenerateEphemeralPrivateKey(rng, privateKey);
00936 GenerateEphemeralPublicKey(rng, privateKey, publicKey);
00937 }
00938
00939 NAMESPACE_END
00940
00941 #endif