Crypto++
cryptlib.cpp
1 // cryptlib.cpp - written and placed in the public domain by Wei Dai
2 
3 #include "pch.h"
4 
5 #ifndef CRYPTOPP_IMPORTS
6 
7 #include "cryptlib.h"
8 #include "misc.h"
9 #include "filters.h"
10 #include "algparam.h"
11 #include "fips140.h"
12 #include "argnames.h"
13 #include "fltrimpl.h"
14 #include "trdlocal.h"
15 #include "osrng.h"
16 
17 #include <memory>
18 
19 NAMESPACE_BEGIN(CryptoPP)
20 
21 CRYPTOPP_COMPILE_ASSERT(sizeof(byte) == 1);
22 CRYPTOPP_COMPILE_ASSERT(sizeof(word16) == 2);
23 CRYPTOPP_COMPILE_ASSERT(sizeof(word32) == 4);
24 CRYPTOPP_COMPILE_ASSERT(sizeof(word64) == 8);
25 #ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
26 CRYPTOPP_COMPILE_ASSERT(sizeof(dword) == 2*sizeof(word));
27 #endif
28 
29 const std::string DEFAULT_CHANNEL;
30 const std::string AAD_CHANNEL = "AAD";
31 const std::string &BufferedTransformation::NULL_CHANNEL = DEFAULT_CHANNEL;
32 
34 {
35 public:
36  bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const {return false;}
37 };
38 
39 simple_ptr<NullNameValuePairs> s_pNullNameValuePairs(new NullNameValuePairs);
40 const NameValuePairs &g_nullNameValuePairs = *s_pNullNameValuePairs.m_p;
41 
43 {
44  static BitBucket bitBucket;
45  return bitBucket;
46 }
47 
48 Algorithm::Algorithm(bool checkSelfTestStatus)
49 {
50  if (checkSelfTestStatus && FIPS_140_2_ComplianceEnabled())
51  {
52  if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_NOT_DONE && !PowerUpSelfTestInProgressOnThisThread())
53  throw SelfTestFailure("Cryptographic algorithms are disabled before the power-up self tests are performed.");
54 
55  if (GetPowerUpSelfTestStatus() == POWER_UP_SELF_TEST_FAILED)
56  throw SelfTestFailure("Cryptographic algorithms are disabled after a power-up self test failed.");
57  }
58 }
59 
60 void SimpleKeyingInterface::SetKey(const byte *key, size_t length, const NameValuePairs &params)
61 {
62  this->ThrowIfInvalidKeyLength(length);
63  this->UncheckedSetKey(key, (unsigned int)length, params);
64 }
65 
66 void SimpleKeyingInterface::SetKeyWithRounds(const byte *key, size_t length, int rounds)
67 {
68  SetKey(key, length, MakeParameters(Name::Rounds(), rounds));
69 }
70 
71 void SimpleKeyingInterface::SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)
72 {
73  SetKey(key, length, MakeParameters(Name::IV(), ConstByteArrayParameter(iv, ivLength)));
74 }
75 
76 void SimpleKeyingInterface::ThrowIfInvalidKeyLength(size_t length)
77 {
78  if (!IsValidKeyLength(length))
79  throw InvalidKeyLength(GetAlgorithm().AlgorithmName(), length);
80 }
81 
82 void SimpleKeyingInterface::ThrowIfResynchronizable()
83 {
84  if (IsResynchronizable())
85  throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object requires an IV");
86 }
87 
88 void SimpleKeyingInterface::ThrowIfInvalidIV(const byte *iv)
89 {
90  if (!iv && IVRequirement() == UNPREDICTABLE_RANDOM_IV)
91  throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": this object cannot use a null IV");
92 }
93 
94 size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(int size)
95 {
96  if (size < 0)
97  return IVSize();
98  else if ((size_t)size < MinIVLength())
99  throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " is less than the minimum of " + IntToString(MinIVLength()));
100  else if ((size_t)size > MaxIVLength())
101  throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": IV length " + IntToString(size) + " exceeds the maximum of " + IntToString(MaxIVLength()));
102  else
103  return size;
104 }
105 
106 const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(const NameValuePairs &params, size_t &size)
107 {
108  ConstByteArrayParameter ivWithLength;
109  const byte *iv;
110  bool found = false;
111 
112  try {found = params.GetValue(Name::IV(), ivWithLength);}
113  catch (const NameValuePairs::ValueTypeMismatch &) {}
114 
115  if (found)
116  {
117  iv = ivWithLength.begin();
118  ThrowIfInvalidIV(iv);
119  size = ThrowIfInvalidIVLength((int)ivWithLength.size());
120  return iv;
121  }
122  else if (params.GetValue(Name::IV(), iv))
123  {
124  ThrowIfInvalidIV(iv);
125  size = IVSize();
126  return iv;
127  }
128  else
129  {
130  ThrowIfResynchronizable();
131  size = 0;
132  return NULL;
133  }
134 }
135 
137 {
138  rng.GenerateBlock(IV, IVSize());
139 }
140 
141 size_t BlockTransformation::AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
142 {
143  size_t blockSize = BlockSize();
144  size_t inIncrement = (flags & (BT_InBlockIsCounter|BT_DontIncrementInOutPointers)) ? 0 : blockSize;
145  size_t xorIncrement = xorBlocks ? blockSize : 0;
146  size_t outIncrement = (flags & BT_DontIncrementInOutPointers) ? 0 : blockSize;
147 
148  if (flags & BT_ReverseDirection)
149  {
150  assert(length % blockSize == 0);
151  inBlocks += length - blockSize;
152  xorBlocks += length - blockSize;
153  outBlocks += length - blockSize;
154  inIncrement = 0-inIncrement;
155  xorIncrement = 0-xorIncrement;
156  outIncrement = 0-outIncrement;
157  }
158 
159  while (length >= blockSize)
160  {
161  if (flags & BT_XorInput)
162  {
163  xorbuf(outBlocks, xorBlocks, inBlocks, blockSize);
164  ProcessBlock(outBlocks);
165  }
166  else
167  ProcessAndXorBlock(inBlocks, xorBlocks, outBlocks);
168  if (flags & BT_InBlockIsCounter)
169  const_cast<byte *>(inBlocks)[blockSize-1]++;
170  inBlocks += inIncrement;
171  outBlocks += outIncrement;
172  xorBlocks += xorIncrement;
173  length -= blockSize;
174  }
175 
176  return length;
177 }
178 
180 {
181  return GetAlignmentOf<word32>();
182 }
183 
185 {
186  return GetAlignmentOf<word32>();
187 }
188 
190 {
191  return GetAlignmentOf<word32>();
192 }
193 
194 void StreamTransformation::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
195 {
196  assert(MinLastBlockSize() == 0); // this function should be overriden otherwise
197 
198  if (length == MandatoryBlockSize())
199  ProcessData(outString, inString, length);
200  else if (length != 0)
201  throw NotImplemented(AlgorithmName() + ": this object does't support a special last block");
202 }
203 
204 void AuthenticatedSymmetricCipher::SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength)
205 {
206  if (headerLength > MaxHeaderLength())
207  throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": header length " + IntToString(headerLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
208 
209  if (messageLength > MaxMessageLength())
210  throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": message length " + IntToString(messageLength) + " exceeds the maximum of " + IntToString(MaxMessageLength()));
211 
212  if (footerLength > MaxFooterLength())
213  throw InvalidArgument(GetAlgorithm().AlgorithmName() + ": footer length " + IntToString(footerLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
214 
215  UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength);
216 }
217 
218 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)
219 {
220  Resynchronize(iv, ivLength);
221  SpecifyDataLengths(headerLength, messageLength);
222  Update(header, headerLength);
223  ProcessString(ciphertext, message, messageLength);
224  TruncatedFinal(mac, macSize);
225 }
226 
227 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)
228 {
229  Resynchronize(iv, ivLength);
230  SpecifyDataLengths(headerLength, ciphertextLength);
231  Update(header, headerLength);
232  ProcessString(message, ciphertext, ciphertextLength);
233  return TruncatedVerify(mac, macLength);
234 }
235 
237 {
238  return GenerateByte() & 1;
239 }
240 
242 {
243  byte b;
244  GenerateBlock(&b, 1);
245  return b;
246 }
247 
248 word32 RandomNumberGenerator::GenerateWord32(word32 min, word32 max)
249 {
250  word32 range = max-min;
251  const int maxBits = BitPrecision(range);
252 
253  word32 value;
254 
255  do
256  {
257  GenerateBlock((byte *)&value, sizeof(value));
258  value = Crop(value, maxBits);
259  } while (value > range);
260 
261  return value+min;
262 }
263 
264 void RandomNumberGenerator::GenerateBlock(byte *output, size_t size)
265 {
266  ArraySink s(output, size);
267  GenerateIntoBufferedTransformation(s, DEFAULT_CHANNEL, size);
268 }
269 
271 {
272  GenerateIntoBufferedTransformation(TheBitBucket(), DEFAULT_CHANNEL, n);
273 }
274 
275 void RandomNumberGenerator::GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
276 {
278  while (length)
279  {
280  size_t len = UnsignedMin(buffer.size(), length);
281  GenerateBlock(buffer, len);
282  target.ChannelPut(channel, buffer, len);
283  length -= len;
284  }
285 }
286 
287 //! see NullRNG()
289 {
290 public:
291  std::string AlgorithmName() const {return "NullRNG";}
292  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");}
293 };
294 
296 {
297  static ClassNullRNG s_nullRNG;
298  return s_nullRNG;
299 }
300 
301 bool HashTransformation::TruncatedVerify(const byte *digestIn, size_t digestLength)
302 {
303  ThrowIfInvalidTruncatedSize(digestLength);
304  SecByteBlock digest(digestLength);
305  TruncatedFinal(digest, digestLength);
306  return VerifyBufsEqual(digest, digestIn, digestLength);
307 }
308 
309 void HashTransformation::ThrowIfInvalidTruncatedSize(size_t size) const
310 {
311  if (size > DigestSize())
312  throw InvalidArgument("HashTransformation: can't truncate a " + IntToString(DigestSize()) + " byte digest to " + IntToString(size) + " bytes");
313 }
314 
316 {
318  return t ? t->GetMaxWaitObjectCount() : 0;
319 }
320 
322 {
324  if (t)
325  t->GetWaitObjects(container, callStack); // reduce clutter by not adding to stack here
326 }
327 
328 void BufferedTransformation::Initialize(const NameValuePairs &parameters, int propagation)
329 {
330  assert(!AttachedTransformation());
331  IsolatedInitialize(parameters);
332 }
333 
334 bool BufferedTransformation::Flush(bool hardFlush, int propagation, bool blocking)
335 {
336  assert(!AttachedTransformation());
337  return IsolatedFlush(hardFlush, blocking);
338 }
339 
340 bool BufferedTransformation::MessageSeriesEnd(int propagation, bool blocking)
341 {
342  assert(!AttachedTransformation());
343  return IsolatedMessageSeriesEnd(blocking);
344 }
345 
346 byte * BufferedTransformation::ChannelCreatePutSpace(const std::string &channel, size_t &size)
347 {
348  if (channel.empty())
349  return CreatePutSpace(size);
350  else
351  throw NoChannelSupport(AlgorithmName());
352 }
353 
354 size_t BufferedTransformation::ChannelPut2(const std::string &channel, const byte *begin, size_t length, int messageEnd, bool blocking)
355 {
356  if (channel.empty())
357  return Put2(begin, length, messageEnd, blocking);
358  else
359  throw NoChannelSupport(AlgorithmName());
360 }
361 
362 size_t BufferedTransformation::ChannelPutModifiable2(const std::string &channel, byte *begin, size_t length, int messageEnd, bool blocking)
363 {
364  if (channel.empty())
365  return PutModifiable2(begin, length, messageEnd, blocking);
366  else
367  return ChannelPut2(channel, begin, length, messageEnd, blocking);
368 }
369 
370 bool BufferedTransformation::ChannelFlush(const std::string &channel, bool completeFlush, int propagation, bool blocking)
371 {
372  if (channel.empty())
373  return Flush(completeFlush, propagation, blocking);
374  else
375  throw NoChannelSupport(AlgorithmName());
376 }
377 
378 bool BufferedTransformation::ChannelMessageSeriesEnd(const std::string &channel, int propagation, bool blocking)
379 {
380  if (channel.empty())
381  return MessageSeriesEnd(propagation, blocking);
382  else
383  throw NoChannelSupport(AlgorithmName());
384 }
385 
387 {
390  else
391  return CopyTo(TheBitBucket());
392 }
393 
395 {
398  else
399  {
400  byte b;
401  return Peek(b) != 0;
402  }
403 }
404 
405 size_t BufferedTransformation::Get(byte &outByte)
406 {
408  return AttachedTransformation()->Get(outByte);
409  else
410  return Get(&outByte, 1);
411 }
412 
413 size_t BufferedTransformation::Get(byte *outString, size_t getMax)
414 {
416  return AttachedTransformation()->Get(outString, getMax);
417  else
418  {
419  ArraySink arraySink(outString, getMax);
420  return (size_t)TransferTo(arraySink, getMax);
421  }
422 }
423 
424 size_t BufferedTransformation::Peek(byte &outByte) const
425 {
427  return AttachedTransformation()->Peek(outByte);
428  else
429  return Peek(&outByte, 1);
430 }
431 
432 size_t BufferedTransformation::Peek(byte *outString, size_t peekMax) const
433 {
435  return AttachedTransformation()->Peek(outString, peekMax);
436  else
437  {
438  ArraySink arraySink(outString, peekMax);
439  return (size_t)CopyTo(arraySink, peekMax);
440  }
441 }
442 
443 lword BufferedTransformation::Skip(lword skipMax)
444 {
446  return AttachedTransformation()->Skip(skipMax);
447  else
448  return TransferTo(TheBitBucket(), skipMax);
449 }
450 
451 lword BufferedTransformation::TotalBytesRetrievable() const
452 {
454  return AttachedTransformation()->TotalBytesRetrievable();
455  else
456  return MaxRetrievable();
457 }
458 
460 {
463  else
464  return CopyMessagesTo(TheBitBucket());
465 }
466 
468 {
471  else
472  return NumberOfMessages() != 0;
473 }
474 
476 {
479  else
480  {
481  assert(!AnyMessages());
482  return false;
483  }
484 }
485 
486 unsigned int BufferedTransformation::SkipMessages(unsigned int count)
487 {
489  return AttachedTransformation()->SkipMessages(count);
490  else
491  return TransferMessagesTo(TheBitBucket(), count);
492 }
493 
494 size_t BufferedTransformation::TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel, bool blocking)
495 {
497  return AttachedTransformation()->TransferMessagesTo2(target, messageCount, channel, blocking);
498  else
499  {
500  unsigned int maxMessages = messageCount;
501  for (messageCount=0; messageCount < maxMessages && AnyMessages(); messageCount++)
502  {
503  size_t blockedBytes;
504  lword transferredBytes;
505 
506  while (AnyRetrievable())
507  {
508  transferredBytes = LWORD_MAX;
509  blockedBytes = TransferTo2(target, transferredBytes, channel, blocking);
510  if (blockedBytes > 0)
511  return blockedBytes;
512  }
513 
514  if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking))
515  return 1;
516 
517  bool result = GetNextMessage();
518  assert(result);
519  }
520  return 0;
521  }
522 }
523 
524 unsigned int BufferedTransformation::CopyMessagesTo(BufferedTransformation &target, unsigned int count, const std::string &channel) const
525 {
527  return AttachedTransformation()->CopyMessagesTo(target, count, channel);
528  else
529  return 0;
530 }
531 
532 void BufferedTransformation::SkipAll()
533 {
535  AttachedTransformation()->SkipAll();
536  else
537  {
538  while (SkipMessages()) {}
539  while (Skip()) {}
540  }
541 }
542 
543 size_t BufferedTransformation::TransferAllTo2(BufferedTransformation &target, const std::string &channel, bool blocking)
544 {
546  return AttachedTransformation()->TransferAllTo2(target, channel, blocking);
547  else
548  {
549  assert(!NumberOfMessageSeries());
550 
551  unsigned int messageCount;
552  do
553  {
554  messageCount = UINT_MAX;
555  size_t blockedBytes = TransferMessagesTo2(target, messageCount, channel, blocking);
556  if (blockedBytes)
557  return blockedBytes;
558  }
559  while (messageCount != 0);
560 
561  lword byteCount;
562  do
563  {
564  byteCount = ULONG_MAX;
565  size_t blockedBytes = TransferTo2(target, byteCount, channel, blocking);
566  if (blockedBytes)
567  return blockedBytes;
568  }
569  while (byteCount != 0);
570 
571  return 0;
572  }
573 }
574 
575 void BufferedTransformation::CopyAllTo(BufferedTransformation &target, const std::string &channel) const
576 {
578  AttachedTransformation()->CopyAllTo(target, channel);
579  else
580  {
581  assert(!NumberOfMessageSeries());
582  while (CopyMessagesTo(target, UINT_MAX, channel)) {}
583  }
584 }
585 
586 void BufferedTransformation::SetRetrievalChannel(const std::string &channel)
587 {
589  AttachedTransformation()->SetRetrievalChannel(channel);
590 }
591 
592 size_t BufferedTransformation::ChannelPutWord16(const std::string &channel, word16 value, ByteOrder order, bool blocking)
593 {
594  PutWord(false, order, m_buf, value);
595  return ChannelPut(channel, m_buf, 2, blocking);
596 }
597 
598 size_t BufferedTransformation::ChannelPutWord32(const std::string &channel, word32 value, ByteOrder order, bool blocking)
599 {
600  PutWord(false, order, m_buf, value);
601  return ChannelPut(channel, m_buf, 4, blocking);
602 }
603 
604 size_t BufferedTransformation::PutWord16(word16 value, ByteOrder order, bool blocking)
605 {
606  return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking);
607 }
608 
609 size_t BufferedTransformation::PutWord32(word32 value, ByteOrder order, bool blocking)
610 {
611  return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking);
612 }
613 
614 size_t BufferedTransformation::PeekWord16(word16 &value, ByteOrder order) const
615 {
616  byte buf[2] = {0, 0};
617  size_t len = Peek(buf, 2);
618 
619  if (order)
620  value = (buf[0] << 8) | buf[1];
621  else
622  value = (buf[1] << 8) | buf[0];
623 
624  return len;
625 }
626 
627 size_t BufferedTransformation::PeekWord32(word32 &value, ByteOrder order) const
628 {
629  byte buf[4] = {0, 0, 0, 0};
630  size_t len = Peek(buf, 4);
631 
632  if (order)
633  value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
634  else
635  value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
636 
637  return len;
638 }
639 
640 size_t BufferedTransformation::GetWord16(word16 &value, ByteOrder order)
641 {
642  return (size_t)Skip(PeekWord16(value, order));
643 }
644 
645 size_t BufferedTransformation::GetWord32(word32 &value, ByteOrder order)
646 {
647  return (size_t)Skip(PeekWord32(value, order));
648 }
649 
651 {
653  AttachedTransformation()->Attach(newOut);
654  else
655  Detach(newOut);
656 }
657 
659 {
660  GenerateRandom(rng, MakeParameters("KeySize", (int)keySize));
661 }
662 
664 {
665 public:
666  PK_DefaultEncryptionFilter(RandomNumberGenerator &rng, const PK_Encryptor &encryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
667  : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters)
668  {
669  Detach(attachment);
670  }
671 
672  size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
673  {
674  FILTER_BEGIN;
675  m_plaintextQueue.Put(inString, length);
676 
677  if (messageEnd)
678  {
679  {
680  size_t plaintextLength;
681  if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength))
682  throw InvalidArgument("PK_DefaultEncryptionFilter: plaintext too long");
683  size_t ciphertextLength = m_encryptor.CiphertextLength(plaintextLength);
684 
685  SecByteBlock plaintext(plaintextLength);
686  m_plaintextQueue.Get(plaintext, plaintextLength);
687  m_ciphertext.resize(ciphertextLength);
688  m_encryptor.Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters);
689  }
690 
691  FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd);
692  }
693  FILTER_END_NO_MESSAGE_END;
694  }
695 
696  RandomNumberGenerator &m_rng;
697  const PK_Encryptor &m_encryptor;
698  const NameValuePairs &m_parameters;
699  ByteQueue m_plaintextQueue;
700  SecByteBlock m_ciphertext;
701 };
702 
704 {
705  return new PK_DefaultEncryptionFilter(rng, *this, attachment, parameters);
706 }
707 
709 {
710 public:
711  PK_DefaultDecryptionFilter(RandomNumberGenerator &rng, const PK_Decryptor &decryptor, BufferedTransformation *attachment, const NameValuePairs &parameters)
712  : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters)
713  {
714  Detach(attachment);
715  }
716 
717  size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
718  {
719  FILTER_BEGIN;
720  m_ciphertextQueue.Put(inString, length);
721 
722  if (messageEnd)
723  {
724  {
725  size_t ciphertextLength;
726  if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength))
727  throw InvalidArgument("PK_DefaultDecryptionFilter: ciphertext too long");
728  size_t maxPlaintextLength = m_decryptor.MaxPlaintextLength(ciphertextLength);
729 
730  SecByteBlock ciphertext(ciphertextLength);
731  m_ciphertextQueue.Get(ciphertext, ciphertextLength);
732  m_plaintext.resize(maxPlaintextLength);
733  m_result = m_decryptor.Decrypt(m_rng, ciphertext, ciphertextLength, m_plaintext, m_parameters);
734  if (!m_result.isValidCoding)
735  throw InvalidCiphertext(m_decryptor.AlgorithmName() + ": invalid ciphertext");
736  }
737 
738  FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd);
739  }
740  FILTER_END_NO_MESSAGE_END;
741  }
742 
743  RandomNumberGenerator &m_rng;
744  const PK_Decryptor &m_decryptor;
745  const NameValuePairs &m_parameters;
746  ByteQueue m_ciphertextQueue;
747  SecByteBlock m_plaintext;
748  DecodingResult m_result;
749 };
750 
752 {
753  return new PK_DefaultDecryptionFilter(rng, *this, attachment, parameters);
754 }
755 
756 size_t PK_Signer::Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
757 {
758  std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
759  return SignAndRestart(rng, *m, signature, false);
760 }
761 
762 size_t PK_Signer::SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const
763 {
764  std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
765  m->Update(message, messageLen);
766  return SignAndRestart(rng, *m, signature, false);
767 }
768 
769 size_t PK_Signer::SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength,
770  const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const
771 {
772  std::auto_ptr<PK_MessageAccumulator> m(NewSignatureAccumulator(rng));
773  InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength);
774  m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
775  return SignAndRestart(rng, *m, signature, false);
776 }
777 
778 bool PK_Verifier::Verify(PK_MessageAccumulator *messageAccumulator) const
779 {
780  std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
781  return VerifyAndRestart(*m);
782 }
783 
784 bool PK_Verifier::VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLength) const
785 {
786  std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
787  InputSignature(*m, signature, signatureLength);
788  m->Update(message, messageLen);
789  return VerifyAndRestart(*m);
790 }
791 
792 DecodingResult PK_Verifier::Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const
793 {
794  std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
795  return RecoverAndRestart(recoveredMessage, *m);
796 }
797 
799  const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength,
800  const byte *signature, size_t signatureLength) const
801 {
802  std::auto_ptr<PK_MessageAccumulator> m(NewVerificationAccumulator());
803  InputSignature(*m, signature, signatureLength);
804  m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
805  return RecoverAndRestart(recoveredMessage, *m);
806 }
807 
808 void SimpleKeyAgreementDomain::GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
809 {
810  GeneratePrivateKey(rng, privateKey);
811  GeneratePublicKey(rng, privateKey, publicKey);
812 }
813 
814 void AuthenticatedKeyAgreementDomain::GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
815 {
816  GenerateStaticPrivateKey(rng, privateKey);
817  GenerateStaticPublicKey(rng, privateKey, publicKey);
818 }
819 
820 void AuthenticatedKeyAgreementDomain::GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
821 {
822  GenerateEphemeralPrivateKey(rng, privateKey);
823  GenerateEphemeralPublicKey(rng, privateKey, publicKey);
824 }
825 
826 NAMESPACE_END
827 
828 #endif
virtual void ProcessLastBlock(byte *outString, const byte *inString, size_t length)
for ciphers where the last block of data is special, encrypt or decrypt the last block of data ...
Definition: cryptlib.cpp:194
used to pass byte array input as part of a NameValuePairs object
Definition: algparam.h:13
exception thrown when an invalid argument is detected
Definition: cryptlib.h:145
virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
generate private/public key pair
Definition: cryptlib.cpp:820
virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL)
generate a random 32 bit word in the range min to max, inclusive
Definition: cryptlib.cpp:248
virtual bool AnyRetrievable() const
returns whether any bytes are currently ready for retrieval
Definition: cryptlib.cpp:394
container of wait objects
Definition: wait.h:146
size_t TransferAllTo2(BufferedTransformation &target, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
returns the number of bytes left in the current transfer block
Definition: cryptlib.cpp:543
virtual size_t SignMessageWithRecovery(RandomNumberGenerator &rng, const byte *recoverableMessage, size_t recoverableMessageLength, const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, byte *signature) const
sign a recoverable message
Definition: cryptlib.cpp:769
virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment=NULL, const NameValuePairs &parameters=g_nullNameValuePairs) const
create a new decryption filter
Definition: cryptlib.cpp:751
virtual void ProcessData(byte *outString, const byte *inString, size_t length)=0
encrypt or decrypt an array of bytes of specified length
size_t TransferMessagesTo2(BufferedTransformation &target, unsigned int &messageCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)
upon return, messageCount contains number of messages that have finished being transfered, and returns the number of bytes left in the current transfer block
Definition: cryptlib.cpp:494
virtual void SetKey(const byte *key, size_t length, const NameValuePairs &params=g_nullNameValuePairs)
set or reset the key of this object
Definition: cryptlib.cpp:60
const char * Rounds()
int
Definition: argnames.h:18
virtual void ProcessAndXorBlock(const byte *inBlock, const byte *xorBlock, byte *outBlock) const =0
encrypt or decrypt inBlock, xor with xorBlock, and write to outBlock
virtual size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)=0
input multiple bytes for blocking or non-blocking processing
virtual size_t Peek(byte &outByte) const
peek at the next byte without removing it from the output buffer
Definition: cryptlib.cpp:424
size_t PeekWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER) const
try to peek at a 16-bit word
Definition: cryptlib.cpp:614
virtual void GenerateBlock(byte *output, size_t size)
generate random array of bytes
Definition: cryptlib.cpp:264
virtual void TruncatedFinal(byte *digest, size_t digestSize)=0
truncated version of Final()
virtual unsigned int OptimalDataAlignment() const
returns how input should be aligned for optimal performance
Definition: cryptlib.cpp:184
void resize(size_type newSize)
change size and preserve contents
Definition: secblock.h:396
interface for public-key encryptors
Definition: cryptlib.h:1224
virtual void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs &parameters=g_nullNameValuePairs) const =0
encrypt a byte string
virtual size_t MaxPlaintextLength(size_t ciphertextLength) const =0
maximum length of plaintext for a given ciphertext length
exception thrown when trying to retrieve a value using a different type than expected ...
Definition: cryptlib.h:231
BufferedTransformation & TheBitBucket()
returns a reference to a BufferedTransformation object that discards all input
Definition: cryptlib.cpp:42
void GenerateBlock(byte *output, size_t size)
generate random array of bytes
Definition: cryptlib.cpp:292
virtual void DiscardBytes(size_t n)
generate and discard n bytes
Definition: cryptlib.cpp:270
virtual size_t TransferTo2(BufferedTransformation &target, lword &byteCount, const std::string &channel=DEFAULT_CHANNEL, bool blocking=true)=0
upon return, byteCount contains number of bytes that have finished being transfered, and returns the number of bytes left in the current transfer block
interface for random number generators
Definition: cryptlib.h:669
void ProcessString(byte *inoutString, size_t length)
same as ProcessData(inoutString, inoutString, length)
Definition: cryptlib.h:499
virtual bool MessageSeriesEnd(int propagation=-1, bool blocking=true)
mark end of a series of messages
Definition: cryptlib.cpp:340
virtual size_t AdvancedProcessBlocks(const byte *inBlocks, const byte *xorBlocks, byte *outBlocks, size_t length, word32 flags) const
encrypt and xor blocks according to flags (see FlagsForAdvancedProcessBlocks)
Definition: cryptlib.cpp:141
void SetKeyWithRounds(const byte *key, size_t length, int rounds)
calls SetKey() with an NameValuePairs object that just specifies &quot;Rounds&quot;
Definition: cryptlib.cpp:66
virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0
check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
virtual bool TruncatedVerify(const byte *digest, size_t digestLength)
truncated version of Verify()
Definition: cryptlib.cpp:301
virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const
recover a message from its signature
Definition: cryptlib.cpp:792
virtual unsigned int SkipMessages(unsigned int count=UINT_MAX)
skip count number of messages
Definition: cryptlib.cpp:486
virtual lword MaxFooterLength() const
the maximum length of AAD that can be input after the encrypted data
Definition: cryptlib.h:643
interface for buffered transformations
Definition: cryptlib.h:771
virtual unsigned int MinIVLength() const
returns minimal length of IVs accepted by this object
Definition: cryptlib.h:398
virtual bool IsValidKeyLength(size_t n) const
returns whether n is a valid key length
Definition: cryptlib.h:363
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: cryptlib.cpp:717
virtual lword MaxHeaderLength() const =0
the maximum length of AAD that can be input before the encrypted data
virtual unsigned int BlockSize() const =0
block size of the cipher in bytes
bool FIPS_140_2_ComplianceEnabled()
returns whether FIPS 140-2 compliance features were enabled at compile time
Definition: fips140.cpp:28
Copy input to a memory buffer.
Definition: filters.h:635
used to return decoding results
Definition: cryptlib.h:198
Algorithm(bool checkSelfTestStatus=true)
Definition: cryptlib.cpp:48
virtual IV_Requirement IVRequirement() const =0
returns the minimal requirement for secure IVs
bool GetValue(const char *name, T &value) const
get a named value, returns true if the name exists
Definition: cryptlib.h:262
lword TransferTo(BufferedTransformation &target, lword transferMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL)
move transferMax bytes of the buffered output to target as input
Definition: cryptlib.h:900
virtual void Attach(BufferedTransformation *newAttachment)
add newAttachment to the end of attachment chain
Definition: cryptlib.cpp:650
virtual bool AnyMessages() const
returns true if NumberOfMessages() &gt; 0
Definition: cryptlib.cpp:467
interface for public-key decryptors
Definition: cryptlib.h:1252
virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment=NULL, const NameValuePairs &parameters=g_nullNameValuePairs) const
create a new encryption filter
Definition: cryptlib.cpp:703
size_t PeekWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER) const
try to peek at a 32-bit word
Definition: cryptlib.cpp:627
virtual void GenerateStaticPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0
generate static private key
exception thrown by a class if a non-implemented method is called
Definition: cryptlib.h:166
virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0
recover a message from its signature
size_t Put(byte inByte, bool blocking=true)
input a byte for processing
Definition: cryptlib.h:785
virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
generate private/public key pair
Definition: cryptlib.cpp:808
void Detach(BufferedTransformation *newAttachment=NULL)
delete the current attachment chain and replace it with newAttachment
Definition: filters.cpp:40
const std::string DEFAULT_CHANNEL
the default channel for BufferedTransformation, equal to the empty string
Definition: cryptlib.cpp:29
exception thrown when a crypto algorithm is used after a self test fails
Definition: fips140.h:14
void ProcessBlock(const byte *inBlock, byte *outBlock) const
encrypt or decrypt one block
Definition: cryptlib.h:437
bool IsResynchronizable() const
returns whether this object can be resynchronized (i.e. supports initialization vectors) ...
Definition: cryptlib.h:386
virtual unsigned int MandatoryBlockSize() const
returns block size, if input must be processed in blocks, otherwise 1
Definition: cryptlib.h:477
virtual void Resynchronize(const byte *iv, int ivLength=-1)
resynchronize with an IV. ivLength=-1 means use IVSize()
Definition: cryptlib.h:402
virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
generate private/public key pair
Definition: cryptlib.cpp:814
virtual bool Flush(bool hardFlush, int propagation=-1, bool blocking=true)
flush buffered input and/or output
Definition: cryptlib.cpp:334
virtual DecodingResult RecoverMessage(byte *recoveredMessage, const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, const byte *signature, size_t signatureLength) const
recover a message from its signature
Definition: cryptlib.cpp:798
virtual std::string AlgorithmName() const
returns name of this algorithm, not universally implemented yet
Definition: cryptlib.h:343
virtual BufferedTransformation * AttachedTransformation()
returns the object immediately attached to this object or NULL for no attachment
Definition: cryptlib.h:1011
const NameValuePairs & g_nullNameValuePairs
empty set of name-value pairs
Definition: cryptlib.cpp:40
virtual lword Skip(lword skipMax=LWORD_MAX)
discard skipMax bytes from the output buffer
Definition: cryptlib.cpp:443
virtual void GenerateStaticPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0
generate static public key
virtual size_t Sign(RandomNumberGenerator &rng, PK_MessageAccumulator *messageAccumulator, byte *signature) const
sign and delete messageAccumulator (even in case of exception thrown)
Definition: cryptlib.cpp:756
virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const
sign a message
Definition: cryptlib.cpp:762
virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV)
get a secure IV for the next message
Definition: cryptlib.cpp:136
RandomNumberGenerator & NullRNG()
returns a reference that can be passed to functions that ask for a RNG but doesn&#39;t actually use it ...
Definition: cryptlib.cpp:295
virtual byte GenerateByte()
generate new random byte and return it
Definition: cryptlib.cpp:241
std::string AlgorithmName() const
returns name of this algorithm, not universally implemented yet
Definition: cryptlib.cpp:291
Byte Queue.
Definition: queue.h:16
virtual bool VerifyMessage(const byte *message, size_t messageLen, const byte *signature, size_t signatureLength) const
check whether input signature is a valid signature for input message
Definition: cryptlib.cpp:784
virtual void GeneratePublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0
generate public key
virtual void GenerateEphemeralPublicKey(RandomNumberGenerator &rng, const byte *privateKey, byte *publicKey) const =0
generate ephemeral public key
virtual PK_MessageAccumulator * NewVerificationAccumulator() const =0
create a new HashTransformation to accumulate the message to be verified
size_t GetWord16(word16 &value, ByteOrder order=BIG_ENDIAN_ORDER)
try to retrieve a 16-bit word
Definition: cryptlib.cpp:640
PowerUpSelfTestStatus GetPowerUpSelfTestStatus()
return the current power-up self test status
Definition: fips140.cpp:38
void GetWaitObjects(WaitObjectContainer &container, CallStack const &callStack)
put wait objects into container
Definition: cryptlib.cpp:321
virtual unsigned int MaxIVLength() const
returns maximal length of IVs accepted by this object
Definition: cryptlib.h:400
see NullRNG()
Definition: cryptlib.cpp:288
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
Definition: argnames.h:16
interface for accumulating messages to be signed or verified
Definition: cryptlib.h:1334
virtual void Detach(BufferedTransformation *newAttachment=0)
delete the current attachment chain and replace it with newAttachment
Definition: cryptlib.h:1016
virtual lword MaxMessageLength() const =0
the maximum length of encrypted data
virtual void GeneratePrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0
generate private key
exception thrown by decryption filters when trying to decrypt an invalid ciphertext ...
Definition: cryptlib.h:159
virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const
check whether messageAccumulator contains a valid signature and message, and delete messageAccumulato...
Definition: cryptlib.cpp:778
size_t PutWord32(word32 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true)
input a 32-bit word
Definition: cryptlib.cpp:609
void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)
calls SetKey() with an NameValuePairs object that just specifies &quot;IV&quot;
Definition: cryptlib.cpp:71
size_t GetWord32(word32 &value, ByteOrder order=BIG_ENDIAN_ORDER)
try to retrieve a 32-bit word
Definition: cryptlib.cpp:645
virtual unsigned int GenerateBit()
generate new random bit and return it
Definition: cryptlib.cpp:236
virtual unsigned int NumberOfMessages() const
number of times MessageEnd() has been received minus messages retrieved or skipped ...
Definition: cryptlib.cpp:459
virtual unsigned int DigestSize() const =0
size of the hash/digest/MAC returned by Final()
virtual unsigned int OptimalDataAlignment() const
returns how inputs and outputs should be aligned for optimal performance
Definition: cryptlib.cpp:179
virtual size_t CiphertextLength(size_t plaintextLength) const =0
calculate length of ciphertext given length of plaintext
virtual void 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)
encrypt and generate MAC in one call. will truncate MAC if macSize &lt; TagSize()
Definition: cryptlib.cpp:218
virtual bool 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)
decrypt and verify MAC in one call, returning true iff MAC is valid. will assume MAC is truncated if ...
Definition: cryptlib.cpp:227
virtual byte * CreatePutSpace(size_t &size)
request space which can be written into by the caller, and then used as input to Put() ...
Definition: cryptlib.h:799
virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs &params=g_nullNameValuePairs)
generate a random key or crypto parameters
Definition: cryptlib.h:1107
void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
calls the above function with a NameValuePairs object that just specifies &quot;KeySize&quot; ...
Definition: cryptlib.cpp:658
size_t PutWord16(word16 value, ByteOrder order=BIG_ENDIAN_ORDER, bool blocking=true)
input a 16-bit word
Definition: cryptlib.cpp:604
virtual lword MaxRetrievable() const
returns number of bytes that is currently ready for retrieval
Definition: cryptlib.cpp:386
unsigned int GetMaxWaitObjectCount() const
maximum number of wait objects that this object can return
Definition: cryptlib.cpp:315
virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0
create a new HashTransformation to accumulate the message to be signed
virtual bool GetNextMessage()
start retrieving the next message
Definition: cryptlib.cpp:475
virtual unsigned int OptimalDataAlignment() const
returns how input should be aligned for optimal performance
Definition: cryptlib.cpp:189
virtual size_t SignAndRestart(RandomNumberGenerator &rng, PK_MessageAccumulator &messageAccumulator, byte *signature, bool restart=true) const =0
sign and restart messageAccumulator
void SpecifyDataLengths(lword headerLength, lword messageLength, lword footerLength=0)
this function only needs to be called if NeedsPrespecifiedDataLengths() returns true ...
Definition: cryptlib.cpp:204
virtual size_t Get(byte &outByte)
try to retrieve a single byte
Definition: cryptlib.cpp:405
lword CopyTo(BufferedTransformation &target, lword copyMax=LWORD_MAX, const std::string &channel=DEFAULT_CHANNEL) const
copy copyMax bytes of the buffered output to target as input
Definition: cryptlib.h:907
virtual void GenerateEphemeralPrivateKey(RandomNumberGenerator &rng, byte *privateKey) const =0
generate ephemeral private key
virtual std::string AlgorithmName() const =0
returns name of this algorithm, not universally implemented yet
virtual void InputSignature(PK_MessageAccumulator &messageAccumulator, const byte *signature, size_t signatureLength) const =0
input signature into a message accumulator
const std::string AAD_CHANNEL
channel for additional authenticated data, equal to &quot;AAD&quot;
Definition: cryptlib.cpp:30
virtual size_t PutModifiable2(byte *inString, size_t length, int messageEnd, bool blocking)
input multiple bytes that may be modified by callee for blocking or non-blocking processing ...
Definition: cryptlib.h:817
virtual void Initialize(const NameValuePairs &parameters=g_nullNameValuePairs, int propagation=-1)
initialize or reinitialize this object
Definition: cryptlib.cpp:328
size_t Get(byte &outByte)
try to retrieve a single byte
Definition: queue.cpp:293
virtual void Update(const byte *input, size_t length)=0
process more input
virtual unsigned int MinLastBlockSize() const
returns the minimum size of the last block, 0 indicating the last block is not special ...
Definition: cryptlib.h:496
virtual bool Attachable()
returns whether this object allows attachment
Definition: cryptlib.h:1009
virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
generate random bytes as input to a BufferedTransformation
Definition: cryptlib.cpp:275
bool GetVoidValue(const char *name, const std::type_info &valueType, void *pValue) const
to be implemented by derived classes, users should use one of the above functions instead ...
Definition: cryptlib.cpp:36
interface for retrieving values given their names
Definition: cryptlib.h:225
virtual DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs &parameters=g_nullNameValuePairs) const =0
decrypt a byte string, and return the length of plaintext
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
Definition: cryptlib.cpp:672