5 #ifndef CRYPTOPP_IMPORTS
19 NAMESPACE_BEGIN(CryptoPP)
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));
31 const std::string &BufferedTransformation::NULL_CHANNEL =
DEFAULT_CHANNEL;
36 bool GetVoidValue(
const char *name,
const std::type_info &valueType,
void *pValue)
const {
return false;}
53 throw SelfTestFailure(
"Cryptographic algorithms are disabled before the power-up self tests are performed.");
56 throw SelfTestFailure(
"Cryptographic algorithms are disabled after a power-up self test failed.");
62 this->ThrowIfInvalidKeyLength(length);
63 this->UncheckedSetKey(key, (
unsigned int)length, params);
76 void SimpleKeyingInterface::ThrowIfInvalidKeyLength(
size_t length)
82 void SimpleKeyingInterface::ThrowIfResynchronizable()
85 throw InvalidArgument(GetAlgorithm().AlgorithmName() +
": this object requires an IV");
88 void SimpleKeyingInterface::ThrowIfInvalidIV(
const byte *iv)
91 throw InvalidArgument(GetAlgorithm().AlgorithmName() +
": this object cannot use a null IV");
94 size_t SimpleKeyingInterface::ThrowIfInvalidIVLength(
int size)
99 throw InvalidArgument(GetAlgorithm().AlgorithmName() +
": IV length " + IntToString(size) +
" is less than the minimum of " + IntToString(
MinIVLength()));
101 throw InvalidArgument(GetAlgorithm().AlgorithmName() +
": IV length " + IntToString(size) +
" exceeds the maximum of " + IntToString(
MaxIVLength()));
106 const byte * SimpleKeyingInterface::GetIVAndThrowIfInvalid(
const NameValuePairs ¶ms,
size_t &size)
117 iv = ivWithLength.begin();
118 ThrowIfInvalidIV(iv);
119 size = ThrowIfInvalidIVLength((
int)ivWithLength.size());
124 ThrowIfInvalidIV(iv);
130 ThrowIfResynchronizable();
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;
148 if (flags & BT_ReverseDirection)
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;
159 while (length >= blockSize)
161 if (flags & BT_XorInput)
163 xorbuf(outBlocks, xorBlocks, inBlocks, blockSize);
168 if (flags & BT_InBlockIsCounter)
169 const_cast<byte *
>(inBlocks)[blockSize-1]++;
170 inBlocks += inIncrement;
171 outBlocks += outIncrement;
172 xorBlocks += xorIncrement;
181 return GetAlignmentOf<word32>();
186 return GetAlignmentOf<word32>();
191 return GetAlignmentOf<word32>();
200 else if (length != 0)
215 UncheckedSpecifyDataLengths(headerLength, messageLength, footerLength);
222 Update(header, headerLength);
231 Update(header, headerLength);
250 word32 range = max-min;
251 const int maxBits = BitPrecision(range);
258 value = Crop(value, maxBits);
259 }
while (value > range);
280 size_t len = UnsignedMin(buffer.size(), length);
282 target.ChannelPut(channel, buffer, len);
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");}
303 ThrowIfInvalidTruncatedSize(digestLength);
306 return VerifyBufsEqual(digest, digestIn, digestLength);
309 void HashTransformation::ThrowIfInvalidTruncatedSize(
size_t size)
const
312 throw InvalidArgument(
"HashTransformation: can't truncate a " + IntToString(
DigestSize()) +
" byte digest to " + IntToString(size) +
" bytes");
331 IsolatedInitialize(parameters);
337 return IsolatedFlush(hardFlush, blocking);
343 return IsolatedMessageSeriesEnd(blocking);
346 byte * BufferedTransformation::ChannelCreatePutSpace(
const std::string &channel,
size_t &size)
354 size_t BufferedTransformation::ChannelPut2(
const std::string &channel,
const byte *begin,
size_t length,
int messageEnd,
bool blocking)
357 return Put2(begin, length, messageEnd, blocking);
362 size_t BufferedTransformation::ChannelPutModifiable2(
const std::string &channel, byte *begin,
size_t length,
int messageEnd,
bool blocking)
367 return ChannelPut2(channel, begin, length, messageEnd, blocking);
370 bool BufferedTransformation::ChannelFlush(
const std::string &channel,
bool completeFlush,
int propagation,
bool blocking)
373 return Flush(completeFlush, propagation, blocking);
378 bool BufferedTransformation::ChannelMessageSeriesEnd(
const std::string &channel,
int propagation,
bool blocking)
410 return Get(&outByte, 1);
429 return Peek(&outByte, 1);
439 return (
size_t)
CopyTo(arraySink, peekMax);
451 lword BufferedTransformation::TotalBytesRetrievable()
const
500 unsigned int maxMessages = messageCount;
501 for (messageCount=0; messageCount < maxMessages &&
AnyMessages(); messageCount++)
504 lword transferredBytes;
508 transferredBytes = LWORD_MAX;
509 blockedBytes =
TransferTo2(target, transferredBytes, channel, blocking);
510 if (blockedBytes > 0)
514 if (target.ChannelMessageEnd(channel, GetAutoSignalPropagation(), blocking))
524 unsigned int BufferedTransformation::CopyMessagesTo(
BufferedTransformation &target,
unsigned int count,
const std::string &channel)
const
532 void BufferedTransformation::SkipAll()
549 assert(!NumberOfMessageSeries());
551 unsigned int messageCount;
554 messageCount = UINT_MAX;
559 while (messageCount != 0);
564 byteCount = ULONG_MAX;
565 size_t blockedBytes =
TransferTo2(target, byteCount, channel, blocking);
569 while (byteCount != 0);
581 assert(!NumberOfMessageSeries());
582 while (CopyMessagesTo(target, UINT_MAX, channel)) {}
586 void BufferedTransformation::SetRetrievalChannel(
const std::string &channel)
592 size_t BufferedTransformation::ChannelPutWord16(
const std::string &channel, word16 value, ByteOrder order,
bool blocking)
594 PutWord(
false, order, m_buf, value);
595 return ChannelPut(channel, m_buf, 2, blocking);
598 size_t BufferedTransformation::ChannelPutWord32(
const std::string &channel, word32 value, ByteOrder order,
bool blocking)
600 PutWord(
false, order, m_buf, value);
601 return ChannelPut(channel, m_buf, 4, blocking);
606 return ChannelPutWord16(DEFAULT_CHANNEL, value, order, blocking);
611 return ChannelPutWord32(DEFAULT_CHANNEL, value, order, blocking);
616 byte buf[2] = {0, 0};
617 size_t len =
Peek(buf, 2);
620 value = (buf[0] << 8) | buf[1];
622 value = (buf[1] << 8) | buf[0];
629 byte buf[4] = {0, 0, 0, 0};
630 size_t len =
Peek(buf, 4);
633 value = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf [3];
635 value = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf [0];
667 : m_rng(rng), m_encryptor(encryptor), m_parameters(parameters)
672 size_t Put2(
const byte *inString,
size_t length,
int messageEnd,
bool blocking)
675 m_plaintextQueue.
Put(inString, length);
680 size_t plaintextLength;
681 if (!SafeConvert(m_plaintextQueue.CurrentSize(), plaintextLength))
682 throw InvalidArgument(
"PK_DefaultEncryptionFilter: plaintext too long");
686 m_plaintextQueue.
Get(plaintext, plaintextLength);
687 m_ciphertext.
resize(ciphertextLength);
688 m_encryptor.
Encrypt(m_rng, plaintext, plaintextLength, m_ciphertext, m_parameters);
691 FILTER_OUTPUT(1, m_ciphertext, m_ciphertext.size(), messageEnd);
693 FILTER_END_NO_MESSAGE_END;
712 : m_rng(rng), m_decryptor(decryptor), m_parameters(parameters)
717 size_t Put2(
const byte *inString,
size_t length,
int messageEnd,
bool blocking)
720 m_ciphertextQueue.
Put(inString, length);
725 size_t ciphertextLength;
726 if (!SafeConvert(m_ciphertextQueue.CurrentSize(), ciphertextLength))
727 throw InvalidArgument(
"PK_DefaultDecryptionFilter: ciphertext too long");
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)
738 FILTER_OUTPUT(1, m_plaintext, m_result.messageLength, messageEnd);
740 FILTER_END_NO_MESSAGE_END;
758 std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
765 m->Update(message, messageLen);
770 const byte *nonrecoverableMessage,
size_t nonrecoverableMessageLength, byte *signature)
const
773 InputRecoverableMessage(*m, recoverableMessage, recoverableMessageLength);
774 m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
780 std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
788 m->Update(message, messageLen);
794 std::auto_ptr<PK_MessageAccumulator> m(messageAccumulator);
799 const byte *nonrecoverableMessage,
size_t nonrecoverableMessageLength,
800 const byte *signature,
size_t signatureLength)
const
804 m->Update(nonrecoverableMessage, nonrecoverableMessageLength);
used to pass byte array input as part of a NameValuePairs object
exception thrown when an invalid argument is detected
virtual void GenerateEphemeralKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
generate private/public key pair
virtual word32 GenerateWord32(word32 a=0, word32 b=0xffffffffL)
generate a random 32 bit word in the range min to max, inclusive
container of wait objects
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
virtual BufferedTransformation * CreateDecryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters=g_nullNameValuePairs) const
create a new decryption filter
virtual void SetKey(const byte *key, size_t length, const NameValuePairs ¶ms=g_nullNameValuePairs)
set or reset the key of this object
virtual void GenerateBlock(byte *output, size_t size)
generate random array of bytes
void resize(size_type newSize)
change size and preserve contents
interface for public-key encryptors
virtual void Encrypt(RandomNumberGenerator &rng, const byte *plaintext, size_t plaintextLength, byte *ciphertext, const NameValuePairs ¶meters=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 ...
BufferedTransformation & TheBitBucket()
returns a reference to a BufferedTransformation object that discards all input
void GenerateBlock(byte *output, size_t size)
generate random array of bytes
virtual void DiscardBytes(size_t n)
generate and discard n bytes
interface for random number generators
void SetKeyWithRounds(const byte *key, size_t length, int rounds)
calls SetKey() with an NameValuePairs object that just specifies "Rounds"
virtual bool VerifyAndRestart(PK_MessageAccumulator &messageAccumulator) const =0
check whether messageAccumulator contains a valid signature and message, and restart messageAccumulat...
virtual DecodingResult Recover(byte *recoveredMessage, PK_MessageAccumulator *messageAccumulator) const
recover a message from its signature
virtual lword MaxFooterLength() const
the maximum length of AAD that can be input after the encrypted data
virtual unsigned int MinIVLength() const
returns minimal length of IVs accepted by this object
virtual bool IsValidKeyLength(size_t n) const
returns whether n is a valid key length
size_t Put2(const byte *inString, size_t length, int messageEnd, bool blocking)
input multiple bytes for blocking or non-blocking processing
virtual lword MaxHeaderLength() const =0
the maximum length of AAD that can be input before the encrypted data
bool FIPS_140_2_ComplianceEnabled()
returns whether FIPS 140-2 compliance features were enabled at compile time
Copy input to a memory buffer.
used to return decoding results
Algorithm(bool checkSelfTestStatus=true)
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
interface for public-key decryptors
virtual BufferedTransformation * CreateEncryptionFilter(RandomNumberGenerator &rng, BufferedTransformation *attachment=NULL, const NameValuePairs ¶meters=g_nullNameValuePairs) const
create a new encryption filter
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
virtual DecodingResult RecoverAndRestart(byte *recoveredMessage, PK_MessageAccumulator &messageAccumulator) const =0
recover a message from its signature
virtual void GenerateKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
generate private/public key pair
void Detach(BufferedTransformation *newAttachment=NULL)
delete the current attachment chain and replace it with newAttachment
const std::string DEFAULT_CHANNEL
the default channel for BufferedTransformation, equal to the empty string
exception thrown when a crypto algorithm is used after a self test fails
bool IsResynchronizable() const
returns whether this object can be resynchronized (i.e. supports initialization vectors) ...
virtual void Resynchronize(const byte *iv, int ivLength=-1)
resynchronize with an IV. ivLength=-1 means use IVSize()
virtual void GenerateStaticKeyPair(RandomNumberGenerator &rng, byte *privateKey, byte *publicKey) const
generate private/public key pair
virtual DecodingResult RecoverMessage(byte *recoveredMessage, const byte *nonrecoverableMessage, size_t nonrecoverableMessageLength, const byte *signature, size_t signatureLength) const
recover a message from its signature
virtual std::string AlgorithmName() const
returns name of this algorithm, not universally implemented yet
const NameValuePairs & g_nullNameValuePairs
empty set of name-value pairs
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)
virtual size_t SignMessage(RandomNumberGenerator &rng, const byte *message, size_t messageLen, byte *signature) const
sign a message
virtual void GetNextIV(RandomNumberGenerator &rng, byte *IV)
get a secure IV for the next message
RandomNumberGenerator & NullRNG()
returns a reference that can be passed to functions that ask for a RNG but doesn't actually use it ...
virtual byte GenerateByte()
generate new random byte and return it
std::string AlgorithmName() const
returns name of this algorithm, not universally implemented yet
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
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
PowerUpSelfTestStatus GetPowerUpSelfTestStatus()
return the current power-up self test status
virtual unsigned int MaxIVLength() const
returns maximal length of IVs accepted by this object
const char * IV()
ConstByteArrayParameter, also accepts const byte * for backwards compatibility.
interface for accumulating messages to be signed or verified
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 ...
virtual bool Verify(PK_MessageAccumulator *messageAccumulator) const
check whether messageAccumulator contains a valid signature and message, and delete messageAccumulato...
void SetKeyWithIV(const byte *key, size_t length, const byte *iv, size_t ivLength)
calls SetKey() with an NameValuePairs object that just specifies "IV"
virtual unsigned int GenerateBit()
generate new random bit and return it
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 < TagSize()
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 ...
virtual void GenerateRandom(RandomNumberGenerator &rng, const NameValuePairs ¶ms=g_nullNameValuePairs)
generate a random key or crypto parameters
void GenerateRandomWithKeySize(RandomNumberGenerator &rng, unsigned int keySize)
calls the above function with a NameValuePairs object that just specifies "KeySize" ...
virtual PK_MessageAccumulator * NewSignatureAccumulator(RandomNumberGenerator &rng) const =0
create a new HashTransformation to accumulate the message to be signed
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 ...
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 "AAD"
size_t Get(byte &outByte)
try to retrieve a single byte
virtual void GenerateIntoBufferedTransformation(BufferedTransformation &target, const std::string &channel, lword length)
generate random bytes as input to a BufferedTransformation
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 ...
interface for retrieving values given their names
virtual DecodingResult Decrypt(RandomNumberGenerator &rng, const byte *ciphertext, size_t ciphertextLength, byte *plaintext, const NameValuePairs ¶meters=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