- Main Page
- Namespaces
- Classes
- Files

# cryptlib.cpp

    00001 // cryptlib.cpp - written and placed in the public domain by Wei Dai
    00002
    00003 #include "pch.h"
    00004
    00005 #ifndef CRYPTOPP_IMPORTS
    00006
    00007 #include "cryptlib.h"
    00008 #include "misc.h"
    00009 #include "filters.h"
    00010 #include "algparam.h"
    00011 #include "fips140.h"
    00012 #include "argnames.h"
    00013 #include "fltrimpl.h"
    00014 #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 &params)
    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 &params, 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);        // this function should be overriden otherwise
    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 //! see NullRNG()
    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);  // reduce clutter by not adding to stack here
    00319 }
    00320
    00321 void BufferedTransformation::Initialize(const NameValuePairs &parameters, 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 &parameters)
    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 &parameters) 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 &parameters)
    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 &parameters) 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