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