2017-01-27 12:05:45 +00:00
// cryptlib.cpp - originally written and placed in the public domain by Wei Dai
2015-11-05 06:59:46 +00:00
# include "pch.h"
# include "config.h"
# if CRYPTOPP_MSC_VERSION
# pragma warning(disable: 4127 4189 4459)
# endif
# if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
# pragma GCC diagnostic ignored "-Wunused-value"
# pragma GCC diagnostic ignored "-Wunused-variable"
# pragma GCC diagnostic ignored "-Wunused-parameter"
# endif
# ifndef CRYPTOPP_IMPORTS
# include "cryptlib.h"
# include "filters.h"
# include "algparam.h"
# include "fips140.h"
# include "argnames.h"
# include "fltrimpl.h"
# include "osrng.h"
# include "secblock.h"
# include "smartptr.h"
2017-12-16 23:18:53 +00:00
# include "stdcpp.h"
2019-07-14 04:52:30 +00:00
# include "misc.h"
2015-11-05 06:59:46 +00:00
NAMESPACE_BEGIN ( CryptoPP )
CRYPTOPP_COMPILE_ASSERT ( sizeof ( byte ) = = 1 ) ;
CRYPTOPP_COMPILE_ASSERT ( sizeof ( word16 ) = = 2 ) ;
CRYPTOPP_COMPILE_ASSERT ( sizeof ( word32 ) = = 4 ) ;
CRYPTOPP_COMPILE_ASSERT ( sizeof ( word64 ) = = 8 ) ;
# ifdef CRYPTOPP_NATIVE_DWORD_AVAILABLE
CRYPTOPP_COMPILE_ASSERT ( sizeof ( dword ) = = 2 * sizeof ( word ) ) ;
# endif
BufferedTransformation & TheBitBucket ( )
{
static BitBucket bitBucket ;
return bitBucket ;
}
Algorithm : : Algorithm ( bool checkSelfTestStatus )
{
if ( checkSelfTestStatus & & FIPS_140_2_ComplianceEnabled ( ) )
{
if ( GetPowerUpSelfTestStatus ( ) = = POWER_UP_SELF_TEST_NOT_DONE & & ! PowerUpSelfTestInProgressOnThisThread ( ) )
throw SelfTestFailure ( " Cryptographic algorithms are disabled before the power-up self tests are performed. " ) ;
if ( GetPowerUpSelfTestStatus ( ) = = POWER_UP_SELF_TEST_FAILED )
throw SelfTestFailure ( " Cryptographic algorithms are disabled after a power-up self test failed. " ) ;
}
}
void SimpleKeyingInterface : : SetKey ( const byte * key , size_t length , const NameValuePairs & params )
{
this - > ThrowIfInvalidKeyLength ( length ) ;
Add variable block size support for block ciphers
This should lead the way for more modern block ciphers like Threefish and Kalyna. It tested well with both regular cipher modes (the mode has an instance of the cipher) and external cipher modes (the cipher and mode are distinct objects, and the mode holds a reference to the cipher).
We still have to work out the details of naming a cipher. For example, Kalyna with a 128-bit key can use a 128-bit or 256-bit block size. Kalyna-128 is not enough to describe the algorithm and locate it in the object registry. Kalyna-128-128 looks kind of weird; maybe Kalyna-128(128) or Kalyna-128(256) would be better.
Here are the initial test cases to verify functionality:
byte key[64] = {}, iv[32] = {};
ECB_Mode<Kalyna>::Encryption enc1;
enc1.SetKey(key, 16);
CBC_Mode<Kalyna>::Encryption enc2;
enc2.SetKeyWithIV(key, 16, iv);
AlgorithmParameters params = MakeParameters
(Name::BlockSize(), 32)
(Name::IV(), ConstByteArrayParameter(iv, 32));
CTR_Mode<Kalyna>::Encryption enc3;
enc3.SetKey(key, 16, params);
CBC_Mode<Kalyna>::Encryption enc4;
enc4.SetKey(key, 32, params);
Kalyna::Encryption enc5;
ECB_Mode_ExternalCipher::Encryption ecb(enc5);
ecb.SetKey(key, 16, params);
Kalyna::Encryption enc6;
ECB_Mode_ExternalCipher::Encryption cbc(enc6);
cbc.SetKey(key, 32, params);
2017-05-01 20:23:57 +00:00
this - > UncheckedSetKey ( key , static_cast < unsigned int > ( length ) , params ) ;
2015-11-05 06:59:46 +00:00
}
void SimpleKeyingInterface : : SetKeyWithRounds ( const byte * key , size_t length , int rounds )
{
SetKey ( key , length , MakeParameters ( Name : : Rounds ( ) , rounds ) ) ;
}
void SimpleKeyingInterface : : SetKeyWithIV ( const byte * key , size_t length , const byte * iv , size_t ivLength )
{
SetKey ( key , length , MakeParameters ( Name : : IV ( ) , ConstByteArrayParameter ( iv , ivLength ) ) ) ;
}
void SimpleKeyingInterface : : ThrowIfInvalidKeyLength ( size_t length )
{
if ( ! IsValidKeyLength ( length ) )
throw InvalidKeyLength ( GetAlgorithm ( ) . AlgorithmName ( ) , length ) ;
}
void SimpleKeyingInterface : : ThrowIfResynchronizable ( )
{
if ( IsResynchronizable ( ) )
throw InvalidArgument ( GetAlgorithm ( ) . AlgorithmName ( ) + " : this object requires an IV " ) ;
}
void SimpleKeyingInterface : : ThrowIfInvalidIV ( const byte * iv )
{
if ( ! iv & & IVRequirement ( ) = = UNPREDICTABLE_RANDOM_IV )
throw InvalidArgument ( GetAlgorithm ( ) . AlgorithmName ( ) + " : this object cannot use a null IV " ) ;
}
2018-01-25 01:04:16 +00:00
size_t SimpleKeyingInterface : : ThrowIfInvalidIVLength ( int length )
{
size_t size = 0 ;
if ( length < 0 )
size = static_cast < size_t > ( IVSize ( ) ) ;
else if ( ( size_t ) length < MinIVLength ( ) )
throw InvalidArgument ( GetAlgorithm ( ) . AlgorithmName ( ) + " : IV length " + IntToString ( length ) + " is less than the minimum of " + IntToString ( MinIVLength ( ) ) ) ;
else if ( ( size_t ) length > MaxIVLength ( ) )
throw InvalidArgument ( GetAlgorithm ( ) . AlgorithmName ( ) + " : IV length " + IntToString ( length ) + " exceeds the maximum of " + IntToString ( MaxIVLength ( ) ) ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = static_cast < size_t > ( length ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
const byte * SimpleKeyingInterface : : GetIVAndThrowIfInvalid ( const NameValuePairs & params , size_t & size )
{
ConstByteArrayParameter ivWithLength ;
2018-01-25 01:04:16 +00:00
const byte * iv = NULLPTR ;
2015-11-05 06:59:46 +00:00
bool found = false ;
try { found = params . GetValue ( Name : : IV ( ) , ivWithLength ) ; }
catch ( const NameValuePairs : : ValueTypeMismatch & ) { }
if ( found )
{
iv = ivWithLength . begin ( ) ;
ThrowIfInvalidIV ( iv ) ;
Add variable block size support for block ciphers
This should lead the way for more modern block ciphers like Threefish and Kalyna. It tested well with both regular cipher modes (the mode has an instance of the cipher) and external cipher modes (the cipher and mode are distinct objects, and the mode holds a reference to the cipher).
We still have to work out the details of naming a cipher. For example, Kalyna with a 128-bit key can use a 128-bit or 256-bit block size. Kalyna-128 is not enough to describe the algorithm and locate it in the object registry. Kalyna-128-128 looks kind of weird; maybe Kalyna-128(128) or Kalyna-128(256) would be better.
Here are the initial test cases to verify functionality:
byte key[64] = {}, iv[32] = {};
ECB_Mode<Kalyna>::Encryption enc1;
enc1.SetKey(key, 16);
CBC_Mode<Kalyna>::Encryption enc2;
enc2.SetKeyWithIV(key, 16, iv);
AlgorithmParameters params = MakeParameters
(Name::BlockSize(), 32)
(Name::IV(), ConstByteArrayParameter(iv, 32));
CTR_Mode<Kalyna>::Encryption enc3;
enc3.SetKey(key, 16, params);
CBC_Mode<Kalyna>::Encryption enc4;
enc4.SetKey(key, 32, params);
Kalyna::Encryption enc5;
ECB_Mode_ExternalCipher::Encryption ecb(enc5);
ecb.SetKey(key, 16, params);
Kalyna::Encryption enc6;
ECB_Mode_ExternalCipher::Encryption cbc(enc6);
cbc.SetKey(key, 32, params);
2017-05-01 20:23:57 +00:00
size = ThrowIfInvalidIVLength ( static_cast < int > ( ivWithLength . size ( ) ) ) ;
2015-11-05 06:59:46 +00:00
}
else if ( params . GetValue ( Name : : IV ( ) , iv ) )
{
ThrowIfInvalidIV ( iv ) ;
2018-01-25 01:04:16 +00:00
size = static_cast < size_t > ( IVSize ( ) ) ;
2015-11-05 06:59:46 +00:00
}
else
{
ThrowIfResynchronizable ( ) ;
size = 0 ;
}
2018-01-25 01:04:16 +00:00
return iv ;
2015-11-05 06:59:46 +00:00
}
2018-01-25 01:04:16 +00:00
void SimpleKeyingInterface : : GetNextIV ( RandomNumberGenerator & rng , byte * iv )
2015-11-05 06:59:46 +00:00
{
2018-01-25 01:04:16 +00:00
rng . GenerateBlock ( iv , IVSize ( ) ) ;
2015-11-05 06:59:46 +00:00
}
size_t BlockTransformation : : AdvancedProcessBlocks ( const byte * inBlocks , const byte * xorBlocks , byte * outBlocks , size_t length , word32 flags ) const
{
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( inBlocks ) ;
CRYPTOPP_ASSERT ( outBlocks ) ;
CRYPTOPP_ASSERT ( length ) ;
2016-08-28 03:52:43 +00:00
2018-07-10 09:00:02 +00:00
const unsigned int blockSize = BlockSize ( ) ;
size_t inIncrement = ( flags & ( BT_InBlockIsCounter | BT_DontIncrementInOutPointers ) ) ? 0 : blockSize ;
size_t xorIncrement = xorBlocks ? blockSize : 0 ;
size_t outIncrement = ( flags & BT_DontIncrementInOutPointers ) ? 0 : blockSize ;
2015-11-05 06:59:46 +00:00
if ( flags & BT_ReverseDirection )
{
2018-07-10 09:00:02 +00:00
inBlocks = PtrAdd ( inBlocks , length - blockSize ) ;
xorBlocks = PtrAdd ( xorBlocks , length - blockSize ) ;
outBlocks = PtrAdd ( outBlocks , length - blockSize ) ;
2015-11-05 06:59:46 +00:00
inIncrement = 0 - inIncrement ;
xorIncrement = 0 - xorIncrement ;
outIncrement = 0 - outIncrement ;
}
2017-05-20 06:37:51 +00:00
// Coverity finding.
2017-12-16 23:18:53 +00:00
const bool xorFlag = xorBlocks & & ( flags & BT_XorInput ) ;
2015-11-05 06:59:46 +00:00
while ( length > = blockSize )
{
2017-05-20 06:37:51 +00:00
if ( xorFlag )
2015-11-05 06:59:46 +00:00
{
2017-05-20 06:37:51 +00:00
// xorBlocks non-NULL and with BT_XorInput.
2015-11-05 06:59:46 +00:00
xorbuf ( outBlocks , xorBlocks , inBlocks , blockSize ) ;
ProcessBlock ( outBlocks ) ;
}
else
2015-11-18 20:32:28 +00:00
{
2017-05-20 06:37:51 +00:00
// xorBlocks may be non-NULL and without BT_XorInput.
2015-11-05 06:59:46 +00:00
ProcessAndXorBlock ( inBlocks , xorBlocks , outBlocks ) ;
2015-11-18 20:32:28 +00:00
}
2015-11-05 06:59:46 +00:00
if ( flags & BT_InBlockIsCounter )
const_cast < byte * > ( inBlocks ) [ blockSize - 1 ] + + ;
2017-12-16 23:18:53 +00:00
2018-07-10 09:00:02 +00:00
inBlocks = PtrAdd ( inBlocks , inIncrement ) ;
outBlocks = PtrAdd ( outBlocks , outIncrement ) ;
xorBlocks = PtrAdd ( xorBlocks , xorIncrement ) ;
2015-11-05 06:59:46 +00:00
length - = blockSize ;
}
return length ;
}
unsigned int BlockTransformation : : OptimalDataAlignment ( ) const
{
return GetAlignmentOf < word32 > ( ) ;
}
unsigned int StreamTransformation : : OptimalDataAlignment ( ) const
{
return GetAlignmentOf < word32 > ( ) ;
}
unsigned int HashTransformation : : OptimalDataAlignment ( ) const
{
return GetAlignmentOf < word32 > ( ) ;
}
2017-09-30 02:34:33 +00:00
#if 0
2015-11-05 06:59:46 +00:00
void StreamTransformation : : ProcessLastBlock ( byte * outString , const byte * inString , size_t length )
{
2016-12-27 17:34:57 +00:00
CRYPTOPP_ASSERT ( MinLastBlockSize ( ) = = 0 ) ; // this function should be overridden otherwise
2015-11-05 06:59:46 +00:00
if ( length = = MandatoryBlockSize ( ) )
ProcessData ( outString , inString , length ) ;
else if ( length ! = 0 )
2016-12-27 17:34:57 +00:00
throw NotImplemented ( AlgorithmName ( ) + " : this object doesn't support a special last block " ) ;
2015-11-05 06:59:46 +00:00
}
2017-09-30 02:34:33 +00:00
# endif
size_t StreamTransformation : : ProcessLastBlock ( byte * outString , size_t outLength , const byte * inString , size_t inLength )
{
// this function should be overridden otherwise
CRYPTOPP_ASSERT ( MinLastBlockSize ( ) = = 0 ) ;
if ( inLength = = MandatoryBlockSize ( ) )
{
2017-10-01 13:32:07 +00:00
outLength = inLength ; // squash unused warning
2017-09-30 02:34:33 +00:00
ProcessData ( outString , inString , inLength ) ;
}
else if ( inLength ! = 0 )
throw NotImplemented ( AlgorithmName ( ) + " : this object doesn't support a special last block " ) ;
2018-01-25 01:04:16 +00:00
return outLength ;
2017-09-30 02:34:33 +00:00
}
2015-11-05 06:59:46 +00:00
void AuthenticatedSymmetricCipher : : SpecifyDataLengths ( lword headerLength , lword messageLength , lword footerLength )
{
if ( headerLength > MaxHeaderLength ( ) )
throw InvalidArgument ( GetAlgorithm ( ) . AlgorithmName ( ) + " : header length " + IntToString ( headerLength ) + " exceeds the maximum of " + IntToString ( MaxHeaderLength ( ) ) ) ;
if ( messageLength > MaxMessageLength ( ) )
throw InvalidArgument ( GetAlgorithm ( ) . AlgorithmName ( ) + " : message length " + IntToString ( messageLength ) + " exceeds the maximum of " + IntToString ( MaxMessageLength ( ) ) ) ;
2016-08-28 03:52:43 +00:00
2015-11-05 06:59:46 +00:00
if ( footerLength > MaxFooterLength ( ) )
throw InvalidArgument ( GetAlgorithm ( ) . AlgorithmName ( ) + " : footer length " + IntToString ( footerLength ) + " exceeds the maximum of " + IntToString ( MaxFooterLength ( ) ) ) ;
UncheckedSpecifyDataLengths ( headerLength , messageLength , footerLength ) ;
}
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 )
{
Resynchronize ( iv , ivLength ) ;
SpecifyDataLengths ( headerLength , messageLength ) ;
Update ( header , headerLength ) ;
ProcessString ( ciphertext , message , messageLength ) ;
TruncatedFinal ( mac , macSize ) ;
}
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 )
{
Resynchronize ( iv , ivLength ) ;
SpecifyDataLengths ( headerLength , ciphertextLength ) ;
Update ( header , headerLength ) ;
ProcessString ( message , ciphertext , ciphertextLength ) ;
return TruncatedVerify ( mac , macLength ) ;
}
2018-04-06 00:34:08 +00:00
std : : string AuthenticatedSymmetricCipher : : AlgorithmName ( ) const
{
// Squash C4505 on Visual Studio 2008 and friends
return " Unknown " ;
}
2015-11-05 06:59:46 +00:00
unsigned int RandomNumberGenerator : : GenerateBit ( )
{
return GenerateByte ( ) & 1 ;
}
byte RandomNumberGenerator : : GenerateByte ( )
{
byte b ;
GenerateBlock ( & b , 1 ) ;
return b ;
}
word32 RandomNumberGenerator : : GenerateWord32 ( word32 min , word32 max )
{
const word32 range = max - min ;
2016-12-02 19:47:31 +00:00
const unsigned int maxBits = BitPrecision ( range ) ;
2015-11-05 06:59:46 +00:00
word32 value ;
do
{
GenerateBlock ( ( byte * ) & value , sizeof ( value ) ) ;
value = Crop ( value , maxBits ) ;
} while ( value > range ) ;
return value + min ;
}
// Stack recursion below... GenerateIntoBufferedTransformation calls GenerateBlock,
// and GenerateBlock calls GenerateIntoBufferedTransformation. Ad infinitum. Also
2017-01-28 10:43:24 +00:00
// see http://github.com/weidai11/cryptopp/issues/38.
2016-08-28 03:52:43 +00:00
//
2015-11-05 06:59:46 +00:00
// According to Wei, RandomNumberGenerator is an interface, and it should not
2016-09-16 15:27:15 +00:00
// be instantiable. Its now spilt milk, and we are going to CRYPTOPP_ASSERT it in Debug
2015-11-05 06:59:46 +00:00
// builds to alert the programmer and throw in Release builds. Developers have
// a reference implementation in case its needed. If a programmer
// unintentionally lands here, then they should ensure use of a
// RandomNumberGenerator pointer or reference so polymorphism can provide the
// proper runtime dispatching.
void RandomNumberGenerator : : GenerateBlock ( byte * output , size_t size )
{
CRYPTOPP_UNUSED ( output ) , CRYPTOPP_UNUSED ( size ) ;
ArraySink s ( output , size ) ;
GenerateIntoBufferedTransformation ( s , DEFAULT_CHANNEL , size ) ;
}
void RandomNumberGenerator : : DiscardBytes ( size_t n )
{
GenerateIntoBufferedTransformation ( TheBitBucket ( ) , DEFAULT_CHANNEL , n ) ;
}
void RandomNumberGenerator : : GenerateIntoBufferedTransformation ( BufferedTransformation & target , const std : : string & channel , lword length )
{
FixedSizeSecBlock < byte , 256 > buffer ;
while ( length )
{
size_t len = UnsignedMin ( buffer . size ( ) , length ) ;
GenerateBlock ( buffer , len ) ;
2017-08-15 08:42:12 +00:00
( void ) target . ChannelPut ( channel , buffer , len ) ;
2015-11-05 06:59:46 +00:00
length - = len ;
}
}
2019-08-16 10:45:30 +00:00
size_t KeyDerivationFunction : : MinDerivedKeyLength ( ) const
2018-03-30 00:18:27 +00:00
{
return 0 ;
}
2019-08-16 10:45:30 +00:00
size_t KeyDerivationFunction : : MaxDerivedKeyLength ( ) const
2018-03-30 00:18:27 +00:00
{
return static_cast < size_t > ( - 1 ) ;
}
2019-08-16 11:12:14 +00:00
void KeyDerivationFunction : : ThrowIfInvalidDerivedKeyLength ( size_t length ) const
2018-03-30 00:18:27 +00:00
{
if ( ! IsValidDerivedLength ( length ) )
2019-08-16 11:12:14 +00:00
throw InvalidDerivedKeyLength ( GetAlgorithm ( ) . AlgorithmName ( ) , length ) ;
2018-03-30 00:18:27 +00:00
}
void KeyDerivationFunction : : SetParameters ( const NameValuePairs & params ) {
CRYPTOPP_UNUSED ( params ) ;
}
2017-11-29 15:54:33 +00:00
/// \brief Random Number Generator that does not produce random numbers
/// \details ClassNullRNG can be used for functions that require a RandomNumberGenerator
/// but don't actually use it. The class throws NotImplemented when a generation function is called.
/// \sa NullRNG()
2015-11-05 06:59:46 +00:00
class ClassNullRNG : public RandomNumberGenerator
{
public :
2017-11-29 15:54:33 +00:00
/// \brief The name of the generator
/// \returns the string \a NullRNGs
2015-11-05 06:59:46 +00:00
std : : string AlgorithmName ( ) const { return " NullRNG " ; }
2016-08-28 03:52:43 +00:00
2015-11-18 20:32:28 +00:00
# if defined(CRYPTOPP_DOXYGEN_PROCESSING)
2017-11-29 15:54:33 +00:00
/// \brief An implementation that throws NotImplemented
2015-11-18 20:32:28 +00:00
byte GenerateByte ( ) { }
2017-11-29 15:54:33 +00:00
/// \brief An implementation that throws NotImplemented
2015-11-18 20:32:28 +00:00
unsigned int GenerateBit ( ) { }
2017-11-29 15:54:33 +00:00
/// \brief An implementation that throws NotImplemented
2015-11-18 20:32:28 +00:00
word32 GenerateWord32 ( word32 min , word32 max ) { }
# endif
2017-11-29 15:54:33 +00:00
/// \brief An implementation that throws NotImplemented
2015-11-05 06:59:46 +00:00
void GenerateBlock ( byte * output , size_t size )
{
CRYPTOPP_UNUSED ( output ) ; CRYPTOPP_UNUSED ( size ) ;
throw NotImplemented ( " NullRNG: NullRNG should only be passed to functions that don't need to generate random bytes " ) ;
}
2015-11-18 20:32:28 +00:00
# if defined(CRYPTOPP_DOXYGEN_PROCESSING)
2017-11-29 15:54:33 +00:00
/// \brief An implementation that throws NotImplemented
2015-11-18 20:32:28 +00:00
void GenerateIntoBufferedTransformation ( BufferedTransformation & target , const std : : string & channel , lword length ) { }
2017-11-29 15:54:33 +00:00
/// \brief An implementation that throws NotImplemented
2015-11-18 20:32:28 +00:00
void IncorporateEntropy ( const byte * input , size_t length ) { }
2017-11-29 15:54:33 +00:00
/// \brief An implementation that returns \p false
2015-11-18 20:32:28 +00:00
bool CanIncorporateEntropy ( ) const { }
2017-11-29 15:54:33 +00:00
/// \brief An implementation that does nothing
2015-11-18 20:32:28 +00:00
void DiscardBytes ( size_t n ) { }
2017-11-29 15:54:33 +00:00
/// \brief An implementation that does nothing
2015-11-18 20:32:28 +00:00
void Shuffle ( IT begin , IT end ) { }
2016-08-28 03:52:43 +00:00
2015-11-18 20:32:28 +00:00
private :
2017-03-01 11:10:06 +00:00
Clonable * Clone ( ) const { return NULLPTR ; }
2015-11-18 20:32:28 +00:00
# endif
2015-11-05 06:59:46 +00:00
} ;
RandomNumberGenerator & NullRNG ( )
{
static ClassNullRNG s_nullRNG ;
return s_nullRNG ;
}
2018-01-25 01:04:16 +00:00
bool HashTransformation : : TruncatedVerify ( const byte * digest , size_t digestLength )
2015-11-05 06:59:46 +00:00
{
2019-07-06 19:57:08 +00:00
// Allocate at least 1 for calculated to avoid triggering diagnostics
2015-11-05 06:59:46 +00:00
ThrowIfInvalidTruncatedSize ( digestLength ) ;
2019-07-06 19:57:08 +00:00
SecByteBlock calculated ( digestLength ? digestLength : 1 ) ;
2018-01-25 01:04:16 +00:00
TruncatedFinal ( calculated , digestLength ) ;
return VerifyBufsEqual ( calculated , digest , digestLength ) ;
2015-11-05 06:59:46 +00:00
}
void HashTransformation : : ThrowIfInvalidTruncatedSize ( size_t size ) const
{
if ( size > DigestSize ( ) )
throw InvalidArgument ( " HashTransformation: can't truncate a " + IntToString ( DigestSize ( ) ) + " byte digest to " + IntToString ( size ) + " bytes " ) ;
}
unsigned int BufferedTransformation : : GetMaxWaitObjectCount ( ) const
{
const BufferedTransformation * t = AttachedTransformation ( ) ;
return t ? t - > GetMaxWaitObjectCount ( ) : 0 ;
}
void BufferedTransformation : : GetWaitObjects ( WaitObjectContainer & container , CallStack const & callStack )
{
BufferedTransformation * t = AttachedTransformation ( ) ;
if ( t )
t - > GetWaitObjects ( container , callStack ) ; // reduce clutter by not adding to stack here
}
void BufferedTransformation : : Initialize ( const NameValuePairs & parameters , int propagation )
{
CRYPTOPP_UNUSED ( propagation ) ;
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( ! AttachedTransformation ( ) ) ;
2015-11-05 06:59:46 +00:00
IsolatedInitialize ( parameters ) ;
}
bool BufferedTransformation : : Flush ( bool hardFlush , int propagation , bool blocking )
{
CRYPTOPP_UNUSED ( propagation ) ;
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( ! AttachedTransformation ( ) ) ;
2015-11-05 06:59:46 +00:00
return IsolatedFlush ( hardFlush , blocking ) ;
}
bool BufferedTransformation : : MessageSeriesEnd ( int propagation , bool blocking )
{
CRYPTOPP_UNUSED ( propagation ) ;
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( ! AttachedTransformation ( ) ) ;
2015-11-05 06:59:46 +00:00
return IsolatedMessageSeriesEnd ( blocking ) ;
}
byte * BufferedTransformation : : ChannelCreatePutSpace ( const std : : string & channel , size_t & size )
{
2018-01-25 01:04:16 +00:00
byte * space = NULLPTR ;
2015-11-05 06:59:46 +00:00
if ( channel . empty ( ) )
2018-01-25 01:04:16 +00:00
space = CreatePutSpace ( size ) ;
2015-11-05 06:59:46 +00:00
else
throw NoChannelSupport ( AlgorithmName ( ) ) ;
2018-01-25 01:04:16 +00:00
return space ;
2015-11-05 06:59:46 +00:00
}
2018-01-25 01:04:16 +00:00
size_t BufferedTransformation : : ChannelPut2 ( const std : : string & channel , const byte * inString , size_t length , int messageEnd , bool blocking )
2015-11-05 06:59:46 +00:00
{
2018-01-25 01:04:16 +00:00
size_t size = 0 ;
2015-11-05 06:59:46 +00:00
if ( channel . empty ( ) )
2018-01-25 01:04:16 +00:00
size = Put2 ( inString , length , messageEnd , blocking ) ;
2015-11-05 06:59:46 +00:00
else
throw NoChannelSupport ( AlgorithmName ( ) ) ;
2018-01-25 01:04:16 +00:00
return size ;
2015-11-05 06:59:46 +00:00
}
2018-01-25 01:04:16 +00:00
size_t BufferedTransformation : : ChannelPutModifiable2 ( const std : : string & channel , byte * inString , size_t length , int messageEnd , bool blocking )
2015-11-05 06:59:46 +00:00
{
2018-01-25 01:04:16 +00:00
size_t size = 0 ;
2015-11-05 06:59:46 +00:00
if ( channel . empty ( ) )
2018-01-25 01:04:16 +00:00
size = PutModifiable2 ( inString , length , messageEnd , blocking ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = ChannelPut2 ( channel , inString , length , messageEnd , blocking ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
2018-01-25 01:04:16 +00:00
bool BufferedTransformation : : ChannelFlush ( const std : : string & channel , bool hardFlush , int propagation , bool blocking )
2015-11-05 06:59:46 +00:00
{
2018-01-25 01:04:16 +00:00
bool result = 0 ;
2015-11-05 06:59:46 +00:00
if ( channel . empty ( ) )
2018-01-25 01:04:16 +00:00
result = Flush ( hardFlush , propagation , blocking ) ;
2015-11-05 06:59:46 +00:00
else
throw NoChannelSupport ( AlgorithmName ( ) ) ;
2018-01-25 01:04:16 +00:00
return result ;
2015-11-05 06:59:46 +00:00
}
bool BufferedTransformation : : ChannelMessageSeriesEnd ( const std : : string & channel , int propagation , bool blocking )
{
2018-01-25 01:04:16 +00:00
bool result = false ;
2015-11-05 06:59:46 +00:00
if ( channel . empty ( ) )
2018-01-25 01:04:16 +00:00
result = MessageSeriesEnd ( propagation , blocking ) ;
2015-11-05 06:59:46 +00:00
else
throw NoChannelSupport ( AlgorithmName ( ) ) ;
2018-01-25 01:04:16 +00:00
return result ;
2015-11-05 06:59:46 +00:00
}
lword BufferedTransformation : : MaxRetrievable ( ) const
{
2018-01-25 01:04:16 +00:00
lword size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > MaxRetrievable ( ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = CopyTo ( TheBitBucket ( ) ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
bool BufferedTransformation : : AnyRetrievable ( ) const
{
2018-01-25 01:04:16 +00:00
bool result = false ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
result = AttachedTransformation ( ) - > AnyRetrievable ( ) ;
2015-11-05 06:59:46 +00:00
else
{
byte b ;
2018-01-25 01:04:16 +00:00
result = Peek ( b ) ! = 0 ;
2015-11-05 06:59:46 +00:00
}
2018-01-25 01:04:16 +00:00
return result ;
2015-11-05 06:59:46 +00:00
}
size_t BufferedTransformation : : Get ( byte & outByte )
{
2018-01-25 01:04:16 +00:00
size_t size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > Get ( outByte ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = Get ( & outByte , 1 ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
size_t BufferedTransformation : : Get ( byte * outString , size_t getMax )
{
2018-01-25 01:04:16 +00:00
size_t size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > Get ( outString , getMax ) ;
2015-11-05 06:59:46 +00:00
else
{
ArraySink arraySink ( outString , getMax ) ;
2018-01-25 01:04:16 +00:00
size = ( size_t ) TransferTo ( arraySink , getMax ) ;
2015-11-05 06:59:46 +00:00
}
2018-01-25 01:04:16 +00:00
return size ;
2015-11-05 06:59:46 +00:00
}
size_t BufferedTransformation : : Peek ( byte & outByte ) const
{
2018-01-25 01:04:16 +00:00
size_t size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > Peek ( outByte ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = Peek ( & outByte , 1 ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
size_t BufferedTransformation : : Peek ( byte * outString , size_t peekMax ) const
{
2018-01-25 01:04:16 +00:00
size_t size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > Peek ( outString , peekMax ) ;
2015-11-05 06:59:46 +00:00
else
{
ArraySink arraySink ( outString , peekMax ) ;
2018-01-25 01:04:16 +00:00
size = ( size_t ) CopyTo ( arraySink , peekMax ) ;
2015-11-05 06:59:46 +00:00
}
2018-01-25 01:04:16 +00:00
return size ;
2015-11-05 06:59:46 +00:00
}
lword BufferedTransformation : : Skip ( lword skipMax )
{
2018-01-25 01:04:16 +00:00
lword size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > Skip ( skipMax ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = TransferTo ( TheBitBucket ( ) , skipMax ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
lword BufferedTransformation : : TotalBytesRetrievable ( ) const
{
2018-01-25 01:04:16 +00:00
lword size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > TotalBytesRetrievable ( ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = MaxRetrievable ( ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
unsigned int BufferedTransformation : : NumberOfMessages ( ) const
{
2018-01-25 01:04:16 +00:00
unsigned int size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > NumberOfMessages ( ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = CopyMessagesTo ( TheBitBucket ( ) ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
bool BufferedTransformation : : AnyMessages ( ) const
{
2018-01-25 01:04:16 +00:00
bool result = false ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
result = AttachedTransformation ( ) - > AnyMessages ( ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
result = NumberOfMessages ( ) ! = 0 ;
return result ;
2015-11-05 06:59:46 +00:00
}
bool BufferedTransformation : : GetNextMessage ( )
{
2018-01-25 01:04:16 +00:00
bool result = false ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
result = AttachedTransformation ( ) - > GetNextMessage ( ) ;
2015-11-05 06:59:46 +00:00
else
{
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( ! AnyMessages ( ) ) ;
2015-11-05 06:59:46 +00:00
}
2018-01-25 01:04:16 +00:00
return result ;
2015-11-05 06:59:46 +00:00
}
unsigned int BufferedTransformation : : SkipMessages ( unsigned int count )
{
2018-01-25 01:04:16 +00:00
unsigned int size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > SkipMessages ( count ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
size = TransferMessagesTo ( TheBitBucket ( ) , count ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
size_t BufferedTransformation : : TransferMessagesTo2 ( BufferedTransformation & target , unsigned int & messageCount , const std : : string & channel , bool blocking )
{
if ( AttachedTransformation ( ) )
return AttachedTransformation ( ) - > TransferMessagesTo2 ( target , messageCount , channel , blocking ) ;
else
{
unsigned int maxMessages = messageCount ;
for ( messageCount = 0 ; messageCount < maxMessages & & AnyMessages ( ) ; messageCount + + )
{
size_t blockedBytes ;
lword transferredBytes ;
while ( AnyRetrievable ( ) )
{
2020-09-12 13:31:02 +00:00
// MaxRetrievable() instead of LWORD_MAX due to GH #962. If
// the target calls CreatePutSpace(), then the allocation
// size will be LWORD_MAX. That happens when target is a
// ByteQueue. Maybe ByteQueue should check the size, and if
// it is LWORD_MAX or -1, then use a default like 4096.
transferredBytes = MaxRetrievable ( ) ;
2015-11-05 06:59:46 +00:00
blockedBytes = TransferTo2 ( target , transferredBytes , channel , blocking ) ;
if ( blockedBytes > 0 )
return blockedBytes ;
}
if ( target . ChannelMessageEnd ( channel , GetAutoSignalPropagation ( ) , blocking ) )
return 1 ;
bool result = GetNextMessage ( ) ;
2016-09-16 15:27:15 +00:00
CRYPTOPP_UNUSED ( result ) ; CRYPTOPP_ASSERT ( result ) ;
2015-11-05 06:59:46 +00:00
}
return 0 ;
}
}
unsigned int BufferedTransformation : : CopyMessagesTo ( BufferedTransformation & target , unsigned int count , const std : : string & channel ) const
{
2018-01-25 01:04:16 +00:00
unsigned int size = 0 ;
2015-11-05 06:59:46 +00:00
if ( AttachedTransformation ( ) )
2018-01-25 01:04:16 +00:00
size = AttachedTransformation ( ) - > CopyMessagesTo ( target , count , channel ) ;
return size ;
2015-11-05 06:59:46 +00:00
}
void BufferedTransformation : : SkipAll ( )
{
if ( AttachedTransformation ( ) )
AttachedTransformation ( ) - > SkipAll ( ) ;
else
{
while ( SkipMessages ( ) ) { }
while ( Skip ( ) ) { }
}
}
size_t BufferedTransformation : : TransferAllTo2 ( BufferedTransformation & target , const std : : string & channel , bool blocking )
{
if ( AttachedTransformation ( ) )
return AttachedTransformation ( ) - > TransferAllTo2 ( target , channel , blocking ) ;
else
{
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( ! NumberOfMessageSeries ( ) ) ;
2015-11-05 06:59:46 +00:00
unsigned int messageCount ;
do
{
messageCount = UINT_MAX ;
size_t blockedBytes = TransferMessagesTo2 ( target , messageCount , channel , blocking ) ;
if ( blockedBytes )
return blockedBytes ;
}
while ( messageCount ! = 0 ) ;
lword byteCount ;
do
{
byteCount = ULONG_MAX ;
size_t blockedBytes = TransferTo2 ( target , byteCount , channel , blocking ) ;
if ( blockedBytes )
return blockedBytes ;
}
while ( byteCount ! = 0 ) ;
return 0 ;
}
}
void BufferedTransformation : : CopyAllTo ( BufferedTransformation & target , const std : : string & channel ) const
{
if ( AttachedTransformation ( ) )
AttachedTransformation ( ) - > CopyAllTo ( target , channel ) ;
else
{
2016-09-16 15:27:15 +00:00
CRYPTOPP_ASSERT ( ! NumberOfMessageSeries ( ) ) ;
2015-11-05 06:59:46 +00:00
while ( CopyMessagesTo ( target , UINT_MAX , channel ) ) { }
}
}
void BufferedTransformation : : SetRetrievalChannel ( const std : : string & channel )
{
if ( AttachedTransformation ( ) )
AttachedTransformation ( ) - > SetRetrievalChannel ( channel ) ;
}
size_t BufferedTransformation : : ChannelPutWord16 ( const std : : string & channel , word16 value , ByteOrder order , bool blocking )
{
PutWord ( false , order , m_buf , value ) ;
return ChannelPut ( channel , m_buf , 2 , blocking ) ;
}
size_t BufferedTransformation : : ChannelPutWord32 ( const std : : string & channel , word32 value , ByteOrder order , bool blocking )
{
PutWord ( false , order , m_buf , value ) ;
return ChannelPut ( channel , m_buf , 4 , blocking ) ;
}
2019-07-10 14:04:58 +00:00
size_t BufferedTransformation : : ChannelPutWord64 ( const std : : string & channel , word64 value , ByteOrder order , bool blocking )
{
PutWord ( false , order , m_buf , value ) ;
return ChannelPut ( channel , m_buf , 8 , blocking ) ;
}
2015-11-05 06:59:46 +00:00
size_t BufferedTransformation : : PutWord16 ( word16 value , ByteOrder order , bool blocking )
{
return ChannelPutWord16 ( DEFAULT_CHANNEL , value , order , blocking ) ;
}
size_t BufferedTransformation : : PutWord32 ( word32 value , ByteOrder order , bool blocking )
{
return ChannelPutWord32 ( DEFAULT_CHANNEL , value , order , blocking ) ;
}
2019-07-10 14:04:58 +00:00
size_t BufferedTransformation : : PutWord64 ( word64 value , ByteOrder order , bool blocking )
{
return ChannelPutWord64 ( DEFAULT_CHANNEL , value , order , blocking ) ;
}
2015-11-05 06:59:46 +00:00
size_t BufferedTransformation : : PeekWord16 ( word16 & value , ByteOrder order ) const
{
byte buf [ 2 ] = { 0 , 0 } ;
size_t len = Peek ( buf , 2 ) ;
2019-07-10 14:04:58 +00:00
if ( order = = BIG_ENDIAN_ORDER )
2019-09-29 01:08:22 +00:00
value = word16 ( ( buf [ 0 ] < < 8 ) | buf [ 1 ] ) ;
2015-11-05 06:59:46 +00:00
else
2019-09-29 01:08:22 +00:00
value = word16 ( ( buf [ 1 ] < < 8 ) | buf [ 0 ] ) ;
2015-11-05 06:59:46 +00:00
return len ;
}
size_t BufferedTransformation : : PeekWord32 ( word32 & value , ByteOrder order ) const
{
byte buf [ 4 ] = { 0 , 0 , 0 , 0 } ;
size_t len = Peek ( buf , 4 ) ;
2019-07-10 14:04:58 +00:00
if ( order = = BIG_ENDIAN_ORDER )
2019-09-29 01:08:22 +00:00
value = word32 ( ( buf [ 0 ] < < 24 ) | ( buf [ 1 ] < < 16 ) |
( buf [ 2 ] < < 8 ) | ( buf [ 3 ] < < 0 ) ) ;
2015-11-05 06:59:46 +00:00
else
2019-09-29 01:08:22 +00:00
value = word32 ( ( buf [ 3 ] < < 24 ) | ( buf [ 2 ] < < 16 ) |
( buf [ 1 ] < < 8 ) | ( buf [ 0 ] < < 0 ) ) ;
2015-11-05 06:59:46 +00:00
return len ;
}
2019-07-10 14:04:58 +00:00
size_t BufferedTransformation : : PeekWord64 ( word64 & value , ByteOrder order ) const
{
byte buf [ 8 ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 } ;
size_t len = Peek ( buf , 8 ) ;
if ( order = = BIG_ENDIAN_ORDER )
value = ( ( word64 ) buf [ 0 ] < < 56 ) | ( ( word64 ) buf [ 1 ] < < 48 ) | ( ( word64 ) buf [ 2 ] < < 40 ) |
( ( word64 ) buf [ 3 ] < < 32 ) | ( ( word64 ) buf [ 4 ] < < 24 ) | ( ( word64 ) buf [ 5 ] < < 16 ) |
( ( word64 ) buf [ 6 ] < < 8 ) | ( word64 ) buf [ 7 ] ;
else
value = ( ( word64 ) buf [ 7 ] < < 56 ) | ( ( word64 ) buf [ 6 ] < < 48 ) | ( ( word64 ) buf [ 5 ] < < 40 ) |
( ( word64 ) buf [ 4 ] < < 32 ) | ( ( word64 ) buf [ 3 ] < < 24 ) | ( ( word64 ) buf [ 2 ] < < 16 ) |
( ( word64 ) buf [ 1 ] < < 8 ) | ( word64 ) buf [ 0 ] ;
return len ;
}
2015-11-05 06:59:46 +00:00
size_t BufferedTransformation : : GetWord16 ( word16 & value , ByteOrder order )
{
return ( size_t ) Skip ( PeekWord16 ( value , order ) ) ;
}
size_t BufferedTransformation : : GetWord32 ( word32 & value , ByteOrder order )
{
return ( size_t ) Skip ( PeekWord32 ( value , order ) ) ;
}
2019-07-10 14:04:58 +00:00
size_t BufferedTransformation : : GetWord64 ( word64 & value , ByteOrder order )
{
return ( size_t ) Skip ( PeekWord64 ( value , order ) ) ;
}
2018-01-25 01:04:16 +00:00
void BufferedTransformation : : Attach ( BufferedTransformation * newAttachment )
2015-11-05 06:59:46 +00:00
{
if ( AttachedTransformation ( ) & & AttachedTransformation ( ) - > Attachable ( ) )
2018-01-25 01:04:16 +00:00
AttachedTransformation ( ) - > Attach ( newAttachment ) ;
2015-11-05 06:59:46 +00:00
else
2018-01-25 01:04:16 +00:00
Detach ( newAttachment ) ;
2015-11-05 06:59:46 +00:00
}
void GeneratableCryptoMaterial : : GenerateRandomWithKeySize ( RandomNumberGenerator & rng , unsigned int keySize )
{
GenerateRandom ( rng , MakeParameters ( " KeySize " , ( int ) keySize ) ) ;
}
class PK_DefaultEncryptionFilter : public Unflushable < Filter >
{
public :
PK_DefaultEncryptionFilter ( RandomNumberGenerator & rng , const PK_Encryptor & encryptor , BufferedTransformation * attachment , const NameValuePairs & parameters )
: m_rng ( rng ) , m_encryptor ( encryptor ) , m_parameters ( parameters )
{
Detach ( attachment ) ;
}
size_t Put2 ( const byte * inString , size_t length , int messageEnd , bool blocking )
{
FILTER_BEGIN ;
m_plaintextQueue . Put ( inString , length ) ;
if ( messageEnd )
{
{
size_t plaintextLength ;
if ( ! SafeConvert ( m_plaintextQueue . CurrentSize ( ) , plaintextLength ) )
throw InvalidArgument ( " PK_DefaultEncryptionFilter: plaintext too long " ) ;
size_t ciphertextLength = m_encryptor . CiphertextLength ( plaintextLength ) ;
SecByteBlock plaintext ( plaintextLength ) ;
m_plaintextQueue . Get ( plaintext , plaintextLength ) ;
m_ciphertext . resize ( ciphertextLength ) ;
m_encryptor . Encrypt ( m_rng , plaintext , plaintextLength , m_ciphertext , m_parameters ) ;
}
2016-08-28 03:52:43 +00:00
2015-11-05 06:59:46 +00:00
FILTER_OUTPUT ( 1 , m_ciphertext , m_ciphertext . size ( ) , messageEnd ) ;
}
FILTER_END_NO_MESSAGE_END ;
}
RandomNumberGenerator & m_rng ;
const PK_Encryptor & m_encryptor ;
const NameValuePairs & m_parameters ;
ByteQueue m_plaintextQueue ;
SecByteBlock m_ciphertext ;
} ;
BufferedTransformation * PK_Encryptor : : CreateEncryptionFilter ( RandomNumberGenerator & rng , BufferedTransformation * attachment , const NameValuePairs & parameters ) const
{
return new PK_DefaultEncryptionFilter ( rng , * this , attachment , parameters ) ;
}
class PK_DefaultDecryptionFilter : public Unflushable < Filter >
{
public :
PK_DefaultDecryptionFilter ( RandomNumberGenerator & rng , const PK_Decryptor & decryptor , BufferedTransformation * attachment , const NameValuePairs & parameters )
: m_rng ( rng ) , m_decryptor ( decryptor ) , m_parameters ( parameters )
{
Detach ( attachment ) ;
}
size_t Put2 ( const byte * inString , size_t length , int messageEnd , bool blocking )
{
FILTER_BEGIN ;
m_ciphertextQueue . Put ( inString , length ) ;
if ( messageEnd )
{
{
size_t ciphertextLength ;
if ( ! SafeConvert ( m_ciphertextQueue . CurrentSize ( ) , ciphertextLength ) )
throw InvalidArgument ( " PK_DefaultDecryptionFilter: ciphertext too long " ) ;
size_t maxPlaintextLength = m_decryptor . MaxPlaintextLength ( ciphertextLength ) ;
SecByteBlock ciphertext ( ciphertextLength ) ;
m_ciphertextQueue . Get ( ciphertext , ciphertextLength ) ;
m_plaintext . resize ( maxPlaintextLength ) ;
m_result = m_decryptor . Decrypt ( m_rng , ciphertext , ciphertextLength , m_plaintext , m_parameters ) ;
if ( ! m_result . isValidCoding )
throw InvalidCiphertext ( m_decryptor . AlgorithmName ( ) + " : invalid ciphertext " ) ;
}
FILTER_OUTPUT ( 1 , m_plaintext , m_result . messageLength , messageEnd ) ;
}
FILTER_END_NO_MESSAGE_END ;
}
RandomNumberGenerator & m_rng ;
const PK_Decryptor & m_decryptor ;
const NameValuePairs & m_parameters ;
ByteQueue m_ciphertextQueue ;
SecByteBlock m_plaintext ;
DecodingResult m_result ;
} ;
BufferedTransformation * PK_Decryptor : : CreateDecryptionFilter ( RandomNumberGenerator & rng , BufferedTransformation * attachment , const NameValuePairs & parameters ) const
{
return new PK_DefaultDecryptionFilter ( rng , * this , attachment , parameters ) ;
}
size_t PK_Signer : : Sign ( RandomNumberGenerator & rng , PK_MessageAccumulator * messageAccumulator , byte * signature ) const
{
member_ptr < PK_MessageAccumulator > m ( messageAccumulator ) ;
return SignAndRestart ( rng , * m , signature , false ) ;
}
size_t PK_Signer : : SignMessage ( RandomNumberGenerator & rng , const byte * message , size_t messageLen , byte * signature ) const
{
member_ptr < PK_MessageAccumulator > m ( NewSignatureAccumulator ( rng ) ) ;
m - > Update ( message , messageLen ) ;
return SignAndRestart ( rng , * m , signature , false ) ;
}
2016-08-28 03:52:43 +00:00
size_t PK_Signer : : SignMessageWithRecovery ( RandomNumberGenerator & rng , const byte * recoverableMessage , size_t recoverableMessageLength ,
2015-11-05 06:59:46 +00:00
const byte * nonrecoverableMessage , size_t nonrecoverableMessageLength , byte * signature ) const
{
member_ptr < PK_MessageAccumulator > m ( NewSignatureAccumulator ( rng ) ) ;
InputRecoverableMessage ( * m , recoverableMessage , recoverableMessageLength ) ;
m - > Update ( nonrecoverableMessage , nonrecoverableMessageLength ) ;
return SignAndRestart ( rng , * m , signature , false ) ;
}
bool PK_Verifier : : Verify ( PK_MessageAccumulator * messageAccumulator ) const
{
member_ptr < PK_MessageAccumulator > m ( messageAccumulator ) ;
return VerifyAndRestart ( * m ) ;
}
2018-01-25 01:04:16 +00:00
bool PK_Verifier : : VerifyMessage ( const byte * message , size_t messageLen , const byte * signature , size_t signatureLen ) const
2015-11-05 06:59:46 +00:00
{
member_ptr < PK_MessageAccumulator > m ( NewVerificationAccumulator ( ) ) ;
2018-01-25 01:04:16 +00:00
InputSignature ( * m , signature , signatureLen ) ;
2015-11-05 06:59:46 +00:00
m - > Update ( message , messageLen ) ;
return VerifyAndRestart ( * m ) ;
}
DecodingResult PK_Verifier : : Recover ( byte * recoveredMessage , PK_MessageAccumulator * messageAccumulator ) const
{
member_ptr < PK_MessageAccumulator > m ( messageAccumulator ) ;
return RecoverAndRestart ( recoveredMessage , * m ) ;
}
2016-08-28 03:52:43 +00:00
DecodingResult PK_Verifier : : RecoverMessage ( byte * recoveredMessage ,
const byte * nonrecoverableMessage , size_t nonrecoverableMessageLength ,
2015-11-05 06:59:46 +00:00
const byte * signature , size_t signatureLength ) const
{
member_ptr < PK_MessageAccumulator > m ( NewVerificationAccumulator ( ) ) ;
InputSignature ( * m , signature , signatureLength ) ;
m - > Update ( nonrecoverableMessage , nonrecoverableMessageLength ) ;
return RecoverAndRestart ( recoveredMessage , * m ) ;
}
void SimpleKeyAgreementDomain : : GenerateKeyPair ( RandomNumberGenerator & rng , byte * privateKey , byte * publicKey ) const
{
GeneratePrivateKey ( rng , privateKey ) ;
GeneratePublicKey ( rng , privateKey , publicKey ) ;
}
void AuthenticatedKeyAgreementDomain : : GenerateStaticKeyPair ( RandomNumberGenerator & rng , byte * privateKey , byte * publicKey ) const
{
GenerateStaticPrivateKey ( rng , privateKey ) ;
GenerateStaticPublicKey ( rng , privateKey , publicKey ) ;
}
void AuthenticatedKeyAgreementDomain : : GenerateEphemeralKeyPair ( RandomNumberGenerator & rng , byte * privateKey , byte * publicKey ) const
{
GenerateEphemeralPrivateKey ( rng , privateKey ) ;
GenerateEphemeralPublicKey ( rng , privateKey , publicKey ) ;
}
2017-01-28 10:43:24 +00:00
// Allow a distro or packager to override the build-time version
// http://github.com/weidai11/cryptopp/issues/371
# ifndef CRYPTOPP_BUILD_VERSION
# define CRYPTOPP_BUILD_VERSION CRYPTOPP_VERSION
# endif
2017-03-14 14:26:51 +00:00
int LibraryVersion ( CRYPTOPP_NOINLINE_DOTDOTDOT )
2017-01-28 10:43:24 +00:00
{
return CRYPTOPP_BUILD_VERSION ;
}
2015-11-05 06:59:46 +00:00
2018-12-03 11:33:15 +00:00
class NullNameValuePairs : public NameValuePairs
{
public :
2021-03-05 03:49:25 +00:00
NullNameValuePairs ( ) { } // Clang complains a default ctor must be available
2018-12-03 11:33:15 +00:00
bool GetVoidValue ( const char * name , const std : : type_info & valueType , void * pValue ) const
{ CRYPTOPP_UNUSED ( name ) ; CRYPTOPP_UNUSED ( valueType ) ; CRYPTOPP_UNUSED ( pValue ) ; return false ; }
} ;
# if HAVE_GCC_INIT_PRIORITY
2018-12-04 08:56:47 +00:00
const std : : string DEFAULT_CHANNEL __attribute__ ( ( init_priority ( CRYPTOPP_INIT_PRIORITY + 25 ) ) ) = " " ;
const std : : string AAD_CHANNEL __attribute__ ( ( init_priority ( CRYPTOPP_INIT_PRIORITY + 26 ) ) ) = " AAD " ;
const NullNameValuePairs s_nullNameValuePairs __attribute__ ( ( init_priority ( CRYPTOPP_INIT_PRIORITY + 27 ) ) ) ;
const NameValuePairs & g_nullNameValuePairs = s_nullNameValuePairs ;
2018-12-03 11:33:15 +00:00
# elif HAVE_MSC_INIT_PRIORITY
2018-12-04 08:56:47 +00:00
# pragma warning(disable: 4073)
# pragma init_seg(lib)
const std : : string DEFAULT_CHANNEL = " " ;
const std : : string AAD_CHANNEL = " AAD " ;
const NullNameValuePairs s_nullNameValuePairs ;
const NameValuePairs & g_nullNameValuePairs = s_nullNameValuePairs ;
# pragma warning(default: 4073)
2018-12-03 11:33:15 +00:00
# elif HAVE_XLC_INIT_PRIORITY
2018-12-04 08:56:47 +00:00
# pragma priority(260)
const std : : string DEFAULT_CHANNEL = " " ;
const std : : string AAD_CHANNEL = " AAD " ;
const NullNameValuePairs s_nullNameValuePairs ;
const NameValuePairs & g_nullNameValuePairs = s_nullNameValuePairs ;
2018-12-03 11:33:15 +00:00
# else
2018-12-04 08:56:47 +00:00
const std : : string DEFAULT_CHANNEL = " " ;
const std : : string AAD_CHANNEL = " AAD " ;
const simple_ptr < NullNameValuePairs > s_pNullNameValuePairs ( new NullNameValuePairs ) ;
const NameValuePairs & g_nullNameValuePairs = * s_pNullNameValuePairs . m_p ;
2018-12-03 11:33:15 +00:00
# endif
2017-03-20 12:51:10 +00:00
NAMESPACE_END // CryptoPP
# endif // CRYPTOPP_IMPORTS