• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

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 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 &params)
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 &params, 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);        // this function should be overriden otherwise
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 //! see NullRNG()
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);  // reduce clutter by not adding to stack here
00326 }
00327 
00328 void BufferedTransformation::Initialize(const NameValuePairs &parameters, 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 &parameters)
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 &parameters) 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 &parameters)
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 &parameters) 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

Generated on Mon Aug 9 2010 15:56:33 for Crypto++ by  doxygen 1.7.1