Crypto++
|
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 ¶ms) 00061 { 00062 this->ThrowIfInvalidKeyLength(length); 00063 this->UncheckedSetKey(key, (unsigned int)length, params); 00064 } 00065 00066 void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds) 00067 { 00068 SetKey(key, length, MakeParameters(Name::Rounds(), rounds)); 00069 } 00070 00071 void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength) 00072 { 00073 SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength))); 00074 } 00075 00076 void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length) 00077 { 00078 if (!IsValidKeyLength(length)) 00079 throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length); 00080 } 00081 00082 void SimpleKeyingInterface::ThrowIfResynchronizable() 00083 { 00084 if (IsResynchronizable()) 00085 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV"); 00086 } 00087 00088 void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv) 00089 { 00090 if (!iv && IVRequirement() == UNPREDICTABLE_RANDOM_IV) 00091 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV"); 00092 } 00093 00094 size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int size) 00095 { 00096 if (size < 0) 00097 return IVSize(); 00098 else if ((size_t)size < MinIVLength()) 00099 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " is less than the minimum of " + IntToString(MinIVLength())); 00100 else if ((size_t)size > MaxIVLength()) 00101 throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " exceeds the maximum of " + IntToString(MaxIVLength())); 00102 else 00103 return size; 00104 } 00105 00106 const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs ¶ms, size_t &size) 00107 { 00108 ConstByteArrayParameter ivWithLength; 00109 const byte *iv; 00110 bool found = false; 00111 00112 try {found = params.GetValue(Name::IV(), ivWithLength);} 00113 catch (const NameValuePairs::ValueTypeMismatch &) {} 00114 00115 if (found) 00116 { 00117 iv = ivWithLength.begin(); 00118 ThrowIfInvalidIV(iv); 00119 size = ThrowIfInvalidIVLength((int)ivWithLength.size()); 00120 return iv; 00121 } 00122 else if (params.GetValue(Name::IV(), iv)) 00123 { 00124 ThrowIfInvalidIV(iv); 00125 size = IVSize(); 00126 return iv; 00127 } 00128 else 00129 { 00130 ThrowIfResynchronizable(); 00131 size = 0; 00132 return NULL; 00133 } 00134 } 00135 00136 void SimpleKeyingInterface::GetNextIV(RandomNumberGenerator &rng, byte *IV) 00137 { 00138 rng.GenerateBlock(IV, IVSize()); 00139 } 00140 00141 size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const 00142 { 00143 size_t blockSize = BlockSize(); 00144 size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize; 00145 size_t xorIncrement = xorBlocks ? blockSize : 0; 00146 size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize; 00147 00148 if (flags & BT_ReverseDirection) 00149 { 00150 assert(length % blockSize == 0); 00151 inBlocks += length - blockSize; 00152 xorBlocks += length - blockSize; 00153 outBlocks += length - blockSize; 00154 inIncrement = 0-inIncrement; 00155 xorIncrement = 0-xorIncrement; 00156 outIncrement = 0-outIncrement; 00157 } 00158 00159 while (length >= blockSize) 00160 { 00161 if (flags & BT_XorInput) 00162 { 00163 xorbuf(outBlocks, xorBlocks, inBlocks, blockSize); 00164 ProcessBlock(outBlocks); 00165 } 00166 else 00167 ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks); 00168 if (flags & BT_InBlockIsCounter) 00169 const_cast<byte *>(inBlocks)[blockSize-1]++; 00170 inBlocks += inIncrement; 00171 outBlocks += outIncrement; 00172 xorBlocks += xorIncrement; 00173 length -= blockSize; 00174 } 00175 00176 return length; 00177 } 00178 00179 unsigned int BlockTransformation::OptimalDataAlignment() const 00180 { 00181 return GetAlignmentOf<word32>(); 00182 } 00183 00184 unsigned int StreamTransformation::OptimalDataAlignment() const 00185 { 00186 return GetAlignmentOf<word32>(); 00187 } 00188 00189 unsigned int HashTransformation::OptimalDataAlignment() const 00190 { 00191 return GetAlignmentOf<word32>(); 00192 } 00193 00194 void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length) 00195 { 00196 assert(MinLastBlockSize() == 0); // 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 ¶meters, int propagation) 00329 { 00330 assert(!AttachedTransformation()); 00331 IsolatedInitialize(parameters); 00332 } 00333 00334 bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking) 00335 { 00336 assert(!AttachedTransformation()); 00337 return IsolatedFlush(hardFlush, blocking); 00338 } 00339 00340 bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking) 00341 { 00342 assert(!AttachedTransformation()); 00343 return IsolatedMessageSeriesEnd(blocking); 00344 } 00345 00346 byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size) 00347 { 00348 if (channel.empty()) 00349 return CreatePutSpace(size); 00350 else 00351 throw NoChannelSupport(AlgorithmName()); 00352 } 00353 00354 size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking) 00355 { 00356 if (channel.empty()) 00357 return Put2(begin, length, messageEnd, blocking); 00358 else 00359 throw NoChannelSupport(AlgorithmName()); 00360 } 00361 00362 size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking) 00363 { 00364 if (channel.empty()) 00365 return PutModifiable2(begin, length, messageEnd, blocking); 00366 else 00367 return ChannelPut2(channel, begin, length, messageEnd, blocking); 00368 } 00369 00370 bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking) 00371 { 00372 if (channel.empty()) 00373 return Flush(completeFlush, propagation, blocking); 00374 else 00375 throw NoChannelSupport(AlgorithmName()); 00376 } 00377 00378 bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking) 00379 { 00380 if (channel.empty()) 00381 return MessageSeriesEnd(propagation, blocking); 00382 else 00383 throw NoChannelSupport(AlgorithmName()); 00384 } 00385 00386 lword BufferedTransformation::MaxRetrievable() const 00387 { 00388 if (AttachedTransformation()) 00389 return AttachedTransformation()->MaxRetrievable(); 00390 else 00391 return CopyTo(TheBitBucket()); 00392 } 00393 00394 bool BufferedTransformation::AnyRetrievable() const 00395 { 00396 if (AttachedTransformation()) 00397 return AttachedTransformation()->AnyRetrievable(); 00398 else 00399 { 00400 byte b; 00401 return Peek(b) != 0; 00402 } 00403 } 00404 00405 size_t BufferedTransformation::Get(byte &outByte) 00406 { 00407 if (AttachedTransformation()) 00408 return AttachedTransformation()->Get(outByte); 00409 else 00410 return Get(&outByte, 1); 00411 } 00412 00413 size_t BufferedTransformation::Get(byte *outString, size_t getMax) 00414 { 00415 if (AttachedTransformation()) 00416 return AttachedTransformation()->Get(outString, getMax); 00417 else 00418 { 00419 ArraySink arraySink(outString, getMax); 00420 return (size_t)TransferTo(arraySink, getMax); 00421 } 00422 } 00423 00424 size_t BufferedTransformation::Peek(byte &outByte) const 00425 { 00426 if (AttachedTransformation()) 00427 return AttachedTransformation()->Peek(outByte); 00428 else 00429 return Peek(&outByte, 1); 00430 } 00431 00432 size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const 00433 { 00434 if (AttachedTransformation()) 00435 return AttachedTransformation()->Peek(outString, peekMax); 00436 else 00437 { 00438 ArraySink arraySink(outString, peekMax); 00439 return (size_t)CopyTo(arraySink, peekMax); 00440 } 00441 } 00442 00443 lword BufferedTransformation::Skip(lword skipMax) 00444 { 00445 if (AttachedTransformation()) 00446 return AttachedTransformation()->Skip(skipMax); 00447 else 00448 return TransferTo(TheBitBucket(), skipMax); 00449 } 00450 00451 lword BufferedTransformation::TotalBytesRetrievable() const 00452 { 00453 if (AttachedTransformation()) 00454 return AttachedTransformation()->TotalBytesRetrievable(); 00455 else 00456 return MaxRetrievable(); 00457 } 00458 00459 unsigned int BufferedTransformation::NumberOfMessages() const 00460 { 00461 if (AttachedTransformation()) 00462 return AttachedTransformation()->NumberOfMessages(); 00463 else 00464 return CopyMessagesTo(TheBitBucket()); 00465 } 00466 00467 bool BufferedTransformation::AnyMessages() const 00468 { 00469 if (AttachedTransformation()) 00470 return AttachedTransformation()->AnyMessages(); 00471 else 00472 return NumberOfMessages() != 0; 00473 } 00474 00475 bool BufferedTransformation::GetNextMessage() 00476 { 00477 if (AttachedTransformation()) 00478 return AttachedTransformation()->GetNextMessage(); 00479 else 00480 { 00481 assert(!AnyMessages()); 00482 return false; 00483 } 00484 } 00485 00486 unsigned int BufferedTransformation::SkipMessages(unsigned int count) 00487 { 00488 if (AttachedTransformation()) 00489 return AttachedTransformation()->SkipMessages(count); 00490 else 00491 return TransferMessagesTo(TheBitBucket(), count); 00492 } 00493 00494 size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking) 00495 { 00496 if (AttachedTransformation()) 00497 return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking); 00498 else 00499 { 00500 unsigned int maxMessages = messageCount; 00501 for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++) 00502 { 00503 size_t blockedBytes; 00504 lword transferredBytes; 00505 00506 while (AnyRetrievable()) 00507 { 00508 transferredBytes = LWORD_MAX; 00509 blockedBytes = TransferTo2(target, transferredBytes, channel, blocking); 00510 if (blockedBytes > 0) 00511 return blockedBytes; 00512 } 00513 00514 if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking)) 00515 return 1; 00516 00517 bool result = GetNextMessage(); 00518 assert(result); 00519 } 00520 return 0; 00521 } 00522 } 00523 00524 unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const 00525 { 00526 if (AttachedTransformation()) 00527 return AttachedTransformation()->CopyMessagesTo(target, count, channel); 00528 else 00529 return 0; 00530 } 00531 00532 void BufferedTransformation::SkipAll() 00533 { 00534 if (AttachedTransformation()) 00535 AttachedTransformation()->SkipAll(); 00536 else 00537 { 00538 while (SkipMessages()) {} 00539 while (Skip()) {} 00540 } 00541 } 00542 00543 size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking) 00544 { 00545 if (AttachedTransformation()) 00546 return AttachedTransformation()->TransferAllTo2(target, channel, blocking); 00547 else 00548 { 00549 assert(!NumberOfMessageSeries()); 00550 00551 unsigned int messageCount; 00552 do 00553 { 00554 messageCount = UINT_MAX; 00555 size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking); 00556 if (blockedBytes) 00557 return blockedBytes; 00558 } 00559 while (messageCount != 0); 00560 00561 lword byteCount; 00562 do 00563 { 00564 byteCount = ULONG_MAX; 00565 size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking); 00566 if (blockedBytes) 00567 return blockedBytes; 00568 } 00569 while (byteCount != 0); 00570 00571 return 0; 00572 } 00573 } 00574 00575 void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const 00576 { 00577 if (AttachedTransformation()) 00578 AttachedTransformation()->CopyAllTo(target, channel); 00579 else 00580 { 00581 assert(!NumberOfMessageSeries()); 00582 while (CopyMessagesTo(target, UINT_MAX, channel)) {} 00583 } 00584 } 00585 00586 void BufferedTransformation::SetRetrievalChannel(const std::string &channel) 00587 { 00588 if (AttachedTransformation()) 00589 AttachedTransformation()->SetRetrievalChannel(channel); 00590 } 00591 00592 size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking) 00593 { 00594 PutWord(false, order, m_buf, value); 00595 return ChannelPut(channel, m_buf, 2, blocking); 00596 } 00597 00598 size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking) 00599 { 00600 PutWord(false, order, m_buf, value); 00601 return ChannelPut(channel, m_buf, 4, blocking); 00602 } 00603 00604 size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking) 00605 { 00606 return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking); 00607 } 00608 00609 size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking) 00610 { 00611 return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking); 00612 } 00613 00614 size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const 00615 { 00616 byte buf[2] = {0, 0}; 00617 size_t len = Peek(buf, 2); 00618 00619 if (order) 00620 value = (buf[0] << 8) | buf[1]; 00621 else 00622 value = (buf[1] << 8) | buf[0]; 00623 00624 return len; 00625 } 00626 00627 size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const 00628 { 00629 byte buf[4] = {0, 0, 0, 0}; 00630 size_t len = Peek(buf, 4); 00631 00632 if (order) 00633 value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3]; 00634 else 00635 value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0]; 00636 00637 return len; 00638 } 00639 00640 size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order) 00641 { 00642 return (size_t)Skip(PeekWord16(value, order)); 00643 } 00644 00645 size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order) 00646 { 00647 return (size_t)Skip(PeekWord32(value, order)); 00648 } 00649 00650 void BufferedTransformation::Attach(BufferedTransformation *newOut) 00651 { 00652 if (AttachedTransformation() && AttachedTransformation()->Attachable()) 00653 AttachedTransformation()->Attach(newOut); 00654 else 00655 Detach(newOut); 00656 } 00657 00658 void GeneratableCryptoMaterial::GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize) 00659 { 00660 GenerateRandom(rng, MakeParameters("KeySize", (int)keySize)); 00661 } 00662 00663 class PK_DefaultEncryptionFilter : public Unflushable<Filter> 00664 { 00665 public: 00666 PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) 00667 : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters) 00668 { 00669 Detach(attachment); 00670 } 00671 00672 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) 00673 { 00674 FILTER_BEGIN; 00675 m_plaintextQueue.Put(inString, length); 00676 00677 if (messageEnd) 00678 { 00679 { 00680 size_t plaintextLength; 00681 if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength)) 00682 throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long"); 00683 size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength); 00684 00685 SecByteBlock plaintext(plaintextLength); 00686 m_plaintextQueue.Get(plaintext, plaintextLength); 00687 m_ciphertext.resize(ciphertextLength); 00688 m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters); 00689 } 00690 00691 FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd); 00692 } 00693 FILTER_END_NO_MESSAGE_END; 00694 } 00695 00696 RandomNumberGenerator &m_rng; 00697 const PK_Encryptor &m_encryptor; 00698 const NameValuePairs &m_parameters; 00699 ByteQueue m_plaintextQueue; 00700 SecByteBlock m_ciphertext; 00701 }; 00702 00703 BufferedTransformation * PK_Encryptor::CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const 00704 { 00705 return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters); 00706 } 00707 00708 class PK_DefaultDecryptionFilter : public Unflushable<Filter> 00709 { 00710 public: 00711 PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs ¶meters) 00712 : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters) 00713 { 00714 Detach(attachment); 00715 } 00716 00717 size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking) 00718 { 00719 FILTER_BEGIN; 00720 m_ciphertextQueue.Put(inString, length); 00721 00722 if (messageEnd) 00723 { 00724 { 00725 size_t ciphertextLength; 00726 if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength)) 00727 throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long"); 00728 size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength); 00729 00730 SecByteBlock ciphertext(ciphertextLength); 00731 m_ciphertextQueue.Get(ciphertext, ciphertextLength); 00732 m_plaintext.resize(maxPlaintextLength); 00733 m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters); 00734 if (!m_result.isValidCoding) 00735 throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext"); 00736 } 00737 00738 FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd); 00739 } 00740 FILTER_END_NO_MESSAGE_END; 00741 } 00742 00743 RandomNumberGenerator &m_rng; 00744 const PK_Decryptor &m_decryptor; 00745 const NameValuePairs &m_parameters; 00746 ByteQueue m_ciphertextQueue; 00747 SecByteBlock m_plaintext; 00748 DecodingResult m_result; 00749 }; 00750 00751 BufferedTransformation * PK_Decryptor::CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment, const NameValuePairs ¶meters) const 00752 { 00753 return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters); 00754 } 00755 00756 size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const 00757 { 00758 std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator); 00759 return SignAndRestart(rng, *m, signature, false); 00760 } 00761 00762 size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const 00763 { 00764 std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng)); 00765 m->Update(message, messageLen); 00766 return SignAndRestart(rng, *m, signature, false); 00767 } 00768 00769 size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, 00770 const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const 00771 { 00772 std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng)); 00773 InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength); 00774 m->Update(nonrecoverableMessage, nonrecoverableMessageLength); 00775 return SignAndRestart(rng, *m, signature, false); 00776 } 00777 00778 bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const 00779 { 00780 std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator); 00781 return VerifyAndRestart(*m); 00782 } 00783 00784 bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLength) const 00785 { 00786 std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator()); 00787 InputSignature(*m, signature, signatureLength); 00788 m->Update(message, messageLen); 00789 return VerifyAndRestart(*m); 00790 } 00791 00792 DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const 00793 { 00794 std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator); 00795 return RecoverAndRestart(recoveredMessage, *m); 00796 } 00797 00798 DecodingResult PK_Verifier::RecoverMessage(byte *recoveredMessage, 00799 const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, 00800 const byte *signature, size_t signatureLength) const 00801 { 00802 std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator()); 00803 InputSignature(*m, signature, signatureLength); 00804 m->Update(nonrecoverableMessage, nonrecoverableMessageLength); 00805 return RecoverAndRestart(recoveredMessage, *m); 00806 } 00807 00808 void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const 00809 { 00810 GeneratePrivateKey(rng, privateKey); 00811 GeneratePublicKey(rng, privateKey, publicKey); 00812 } 00813 00814 void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const 00815 { 00816 GenerateStaticPrivateKey(rng, privateKey); 00817 GenerateStaticPublicKey(rng, privateKey, publicKey); 00818 } 00819 00820 void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const 00821 { 00822 GenerateEphemeralPrivateKey(rng, privateKey); 00823 GenerateEphemeralPublicKey(rng, privateKey, publicKey); 00824 } 00825 00826 NAMESPACE_END 00827 00828 #endif