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