2017-01-27 12:05:45 +00:00
|
|
|
// seckey.h - originally written and placed in the public domain by Wei Dai
|
2015-11-05 06:59:46 +00:00
|
|
|
|
2016-12-02 19:47:31 +00:00
|
|
|
//! \file seckey.h
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \brief Classes and functions for implementing secret key algorithms.
|
2015-11-05 06:59:46 +00:00
|
|
|
|
|
|
|
#ifndef CRYPTOPP_SECKEY_H
|
|
|
|
#define CRYPTOPP_SECKEY_H
|
|
|
|
|
2015-11-19 21:48:56 +00:00
|
|
|
#include "config.h"
|
2016-12-02 19:47:31 +00:00
|
|
|
#include "cryptlib.h"
|
|
|
|
#include "misc.h"
|
|
|
|
#include "simple.h"
|
2015-11-05 06:59:46 +00:00
|
|
|
|
|
|
|
#if CRYPTOPP_MSC_VERSION
|
2015-12-17 06:39:13 +00:00
|
|
|
# pragma warning(push)
|
|
|
|
# pragma warning(disable: 4189)
|
2015-11-05 06:59:46 +00:00
|
|
|
#endif
|
|
|
|
|
2016-12-02 19:47:31 +00:00
|
|
|
// Issue 340
|
|
|
|
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
|
|
|
|
# pragma GCC diagnostic push
|
|
|
|
# pragma GCC diagnostic ignored "-Wconversion"
|
|
|
|
# pragma GCC diagnostic ignored "-Wsign-conversion"
|
|
|
|
#endif
|
2015-11-05 06:59:46 +00:00
|
|
|
|
|
|
|
NAMESPACE_BEGIN(CryptoPP)
|
|
|
|
|
|
|
|
//! \brief Inverts the cipher's direction
|
|
|
|
//! \param dir the cipher's direction
|
2015-12-17 06:37:01 +00:00
|
|
|
//! \returns DECRYPTION if \ref CipherDir "dir" is ENCRYPTION, DECRYPTION otherwise
|
2015-11-05 06:59:46 +00:00
|
|
|
inline CipherDir ReverseCipherDir(CipherDir dir)
|
|
|
|
{
|
|
|
|
return (dir == ENCRYPTION) ? DECRYPTION : ENCRYPTION;
|
|
|
|
}
|
|
|
|
|
|
|
|
//! \class FixedBlockSize
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief Inherited by algorithms with fixed block size
|
|
|
|
//! \tparam N the blocksize of the algorithm
|
2015-11-05 06:59:46 +00:00
|
|
|
template <unsigned int N>
|
|
|
|
class FixedBlockSize
|
|
|
|
{
|
|
|
|
public:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The block size of the algorithm provided as a constant.
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(BLOCKSIZE = N)
|
2017-05-04 02:34:37 +00:00
|
|
|
//! \brief The default blocksize for the algorithm provided as a constant.
|
|
|
|
CRYPTOPP_CONSTANT(DEFAULT_BLOCKSIZE = N)
|
|
|
|
//! \brief The minimum blocksize for the algorithm provided as a constant.
|
|
|
|
CRYPTOPP_CONSTANT(MIN_BLOCKSIZE = N)
|
|
|
|
//! \brief The maximum blocksize for the algorithm provided as a constant.
|
|
|
|
CRYPTOPP_CONSTANT(MAX_BLOCKSIZE = N)
|
|
|
|
//! \brief The default block size for the algorithm provided by a static function.
|
|
|
|
//! \param blocksize the block size, in bytes
|
|
|
|
//! \details The default implementation returns BLOCKSIZE. blocksize is unused
|
|
|
|
//! in the default implementation.
|
|
|
|
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidBlockSize(size_t blocksize)
|
|
|
|
{
|
|
|
|
return CRYPTOPP_UNUSED(blocksize), static_cast<size_t>(BLOCKSIZE);
|
|
|
|
}
|
|
|
|
//! \brief The default block size under a key provided by a static function.
|
|
|
|
//! \param keylength the size of the key, in bytes
|
|
|
|
//! \param blocksize the block size, in bytes
|
|
|
|
//! \details The default implementation returns BLOCKSIZE. blocksize is unused
|
|
|
|
//! in the default implementation.
|
|
|
|
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidBlockSize(size_t keylength, size_t blocksize)
|
|
|
|
{
|
|
|
|
return CRYPTOPP_UNUSED(keylength), CRYPTOPP_UNUSED(blocksize), static_cast<size_t>(BLOCKSIZE);
|
|
|
|
}
|
2015-11-05 06:59:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
// ************** rounds ***************
|
|
|
|
|
|
|
|
//! \class FixedRounds
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief Inherited by algorithms with fixed number of rounds
|
|
|
|
//! \tparam R the number of rounds used by the algorithm
|
2015-11-05 06:59:46 +00:00
|
|
|
template <unsigned int R>
|
|
|
|
class FixedRounds
|
|
|
|
{
|
|
|
|
public:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The number of rounds for the algorithm provided as a constant.
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(ROUNDS = R)
|
|
|
|
};
|
|
|
|
|
|
|
|
//! \class VariableRounds
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief Inherited by algorithms with variable number of rounds
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \tparam D Default number of rounds
|
|
|
|
//! \tparam N Minimum number of rounds
|
2016-11-17 14:16:09 +00:00
|
|
|
//! \tparam M Maximum number of rounds
|
2015-11-05 06:59:46 +00:00
|
|
|
template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX> // use INT_MAX here because enums are treated as signed ints
|
|
|
|
class VariableRounds
|
|
|
|
{
|
|
|
|
public:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default number of rounds for the algorithm provided as a constant.
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(DEFAULT_ROUNDS = D)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The minimum number of rounds for the algorithm provided as a constant.
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(MIN_ROUNDS = N)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The maximum number of rounds for the algorithm provided as a constant.
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(MAX_ROUNDS = M)
|
2016-09-05 07:13:45 +00:00
|
|
|
//! \brief The default number of rounds for the algorithm based on key length
|
2015-11-05 06:59:46 +00:00
|
|
|
//! provided by a static function.
|
|
|
|
//! \param keylength the size of the key, in bytes
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details keylength is unused in the default implementation.
|
2016-11-13 16:50:34 +00:00
|
|
|
CRYPTOPP_STATIC_CONSTEXPR unsigned int StaticGetDefaultRounds(size_t keylength)
|
2016-09-07 13:32:06 +00:00
|
|
|
{
|
|
|
|
return CRYPTOPP_UNUSED(keylength), static_cast<unsigned int>(DEFAULT_ROUNDS);
|
|
|
|
}
|
2015-11-05 06:59:46 +00:00
|
|
|
|
|
|
|
protected:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief Validates the number of rounds for an algorithm.
|
2016-09-07 13:32:06 +00:00
|
|
|
//! \param rounds the candidate number of rounds
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \param alg an Algorithm object used if the number of rounds are invalid
|
|
|
|
//! \throws InvalidRounds if the number of rounds are invalid
|
2016-09-05 07:13:45 +00:00
|
|
|
//! \details ThrowIfInvalidRounds() validates the number of rounds and throws if invalid.
|
2015-11-05 06:59:46 +00:00
|
|
|
inline void ThrowIfInvalidRounds(int rounds, const Algorithm *alg)
|
|
|
|
{
|
2016-09-04 12:10:43 +00:00
|
|
|
if (M == INT_MAX) // Coverity and result_independent_of_operands
|
|
|
|
{
|
|
|
|
if (rounds < MIN_ROUNDS)
|
|
|
|
throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (rounds < MIN_ROUNDS || rounds > MAX_ROUNDS)
|
|
|
|
throw InvalidRounds(alg ? alg->AlgorithmName() : std::string("VariableRounds"), rounds);
|
|
|
|
}
|
2015-11-05 06:59:46 +00:00
|
|
|
}
|
|
|
|
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief Validates the number of rounds for an algorithm
|
2016-09-07 13:32:06 +00:00
|
|
|
//! \param param the candidate number of rounds
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \param alg an Algorithm object used if the number of rounds are invalid
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \returns the number of rounds for the algorithm
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \throws InvalidRounds if the number of rounds are invalid
|
2016-09-05 07:13:45 +00:00
|
|
|
//! \details GetRoundsAndThrowIfInvalid() validates the number of rounds and throws if invalid.
|
2015-11-05 06:59:46 +00:00
|
|
|
inline unsigned int GetRoundsAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg)
|
|
|
|
{
|
|
|
|
int rounds = param.GetIntValueWithDefault("Rounds", DEFAULT_ROUNDS);
|
|
|
|
ThrowIfInvalidRounds(rounds, alg);
|
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
|
|
|
return static_cast<unsigned int>(rounds);
|
2015-11-05 06:59:46 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
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
|
|
|
//! \class VariableBlockSize
|
|
|
|
//! \brief Inherited by algorithms with variable blocksize
|
|
|
|
//! \tparam D Default blocksize
|
|
|
|
//! \tparam N Minimum blocksize
|
|
|
|
//! \tparam M Maximum blocksize
|
|
|
|
template <unsigned int D, unsigned int N=1, unsigned int M=INT_MAX> // use INT_MAX here because enums are treated as signed ints
|
|
|
|
class VariableBlockSize
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
//! \brief The default blocksize for the algorithm provided as a constant.
|
|
|
|
CRYPTOPP_CONSTANT(DEFAULT_BLOCKSIZE = D)
|
|
|
|
//! \brief The minimum blocksize for the algorithm provided as a constant.
|
|
|
|
CRYPTOPP_CONSTANT(MIN_BLOCKSIZE = N)
|
|
|
|
//! \brief The maximum blocksize for the algorithm provided as a constant.
|
|
|
|
CRYPTOPP_CONSTANT(MAX_BLOCKSIZE = M)
|
2017-05-04 02:34:37 +00:00
|
|
|
//! \brief The default block size for the algorithm provided by a static function.
|
|
|
|
//! \param blocksize the block size, in bytes
|
|
|
|
//! \details The default implementation returns BLOCKSIZE. blocksize is unused
|
|
|
|
//! in the default implementation.
|
|
|
|
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidBlockSize(size_t blocksize)
|
|
|
|
{
|
|
|
|
return CRYPTOPP_UNUSED(blocksize), static_cast<size_t>(DEFAULT_BLOCKSIZE);
|
|
|
|
}
|
|
|
|
//! \brief The default block size under a key provided by a static function.
|
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
|
|
|
//! \param keylength the size of the key, in bytes
|
2017-05-04 02:34:37 +00:00
|
|
|
//! \param blocksize the block size, in bytes
|
|
|
|
//! \details The default implementation returns BLOCKSIZE. blocksize is unused
|
|
|
|
//! in the default implementation.
|
|
|
|
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidBlockSize(size_t keylength, size_t blocksize)
|
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
|
|
|
{
|
2017-05-04 02:34:37 +00:00
|
|
|
return CRYPTOPP_UNUSED(keylength), CRYPTOPP_UNUSED(blocksize), static_cast<size_t>(DEFAULT_BLOCKSIZE);
|
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
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
|
|
|
//! \brief Validates the blocksize for an algorithm.
|
|
|
|
//! \param blocksize the candidate blocksize
|
|
|
|
//! \param alg an Algorithm object used if the blocksize is invalid
|
|
|
|
//! \throws InvalidBlockSize if the blocksize is invalid
|
|
|
|
//! \details ThrowIfInvalidBlockSize() validates the blocksize and throws if invalid.
|
|
|
|
inline void ThrowIfInvalidBlockSize(int blocksize, const Algorithm *alg)
|
|
|
|
{
|
|
|
|
if (M == INT_MAX) // Coverity and result_independent_of_operands
|
|
|
|
{
|
|
|
|
if (blocksize < MIN_BLOCKSIZE)
|
|
|
|
throw InvalidBlockSize(alg ? alg->AlgorithmName() : std::string("VariableBlockSize"), blocksize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (blocksize < MIN_BLOCKSIZE || blocksize > MAX_BLOCKSIZE)
|
|
|
|
throw InvalidBlockSize(alg ? alg->AlgorithmName() : std::string("VariableBlockSize"), blocksize);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//! \brief Validates the blocksize for an algorithm
|
|
|
|
//! \param param the candidate blocksize
|
|
|
|
//! \param alg an Algorithm object used if the blocksize is invalid
|
|
|
|
//! \returns the blocksize for the algorithm
|
|
|
|
//! \throws InvalidBlockSize if the blocksize is invalid
|
|
|
|
//! \details GetBlockSizeAndThrowIfInvalid() validates the blocksize and throws if invalid.
|
|
|
|
inline unsigned int GetBlockSizeAndThrowIfInvalid(const NameValuePairs ¶m, const Algorithm *alg)
|
|
|
|
{
|
|
|
|
int keylength = param.GetIntValueWithDefault("KeySize", 0);
|
|
|
|
int blocksize = param.GetIntValueWithDefault("BlockSize", DEFAULT_BLOCKSIZE);
|
|
|
|
if (keylength > 0)
|
|
|
|
ThrowIfInvalidBlockSize(keylength, blocksize, alg);
|
|
|
|
else
|
|
|
|
ThrowIfInvalidBlockSize(blocksize, alg);
|
|
|
|
return static_cast<unsigned int>(blocksize);
|
|
|
|
}
|
|
|
|
|
|
|
|
//! Provides the block size of the cipher
|
|
|
|
//! \return the block size, in bytes
|
|
|
|
//! \details The sematics of BlockSize() is return DEFAULT_BLOCKSIZE if the default blocksize
|
|
|
|
//! is in effect. If the blocksize has changed, then the value returned is the BlockSize()
|
|
|
|
//! parameter used during SetKey().
|
|
|
|
//! \details DEFAULT_BLOCKSIZE should be paired with DEFAULT_KEYLENGTH, and it is the same as
|
|
|
|
//! BLOCKSIZE in a FixedBlockSize cipher.
|
|
|
|
virtual unsigned int BlockSize() const =0;
|
|
|
|
|
|
|
|
//! Provides the minimum block size of the cipher
|
|
|
|
//! \return the minimum block size, in bytes
|
|
|
|
//! \details MinBlockSize() returns the smallest blocksize a cipher can use. The size can
|
|
|
|
//! be affected by the key length. For example, Threefish has key sizes of 256, 512 and 1024 bits,
|
|
|
|
//! and the blocksize follows the key length. If a 512-bit key is used, then the block size is 512
|
|
|
|
//! bits. Once keyed, the minimum block size of 256 is not accurate, nor is a block size of 1024 bit.
|
|
|
|
virtual unsigned int MinBlockSize() const
|
|
|
|
{ return MIN_BLOCKSIZE; }
|
|
|
|
|
|
|
|
//! Provides the maximum block size of the cipher
|
|
|
|
//! \return the maximum block size, in bytes
|
|
|
|
//! \details MaxBlockSize() returns the largest blocksize a cipher can use. The size can
|
|
|
|
//! be affected by the key length. For example, Threefish has key sizes of 256, 512 and 1024 bits,
|
|
|
|
//! and the blocksize follows the key length. If a 512-bit key is used, then the block size is 512
|
|
|
|
//! bits. Once keyed, the minimum block size of 256 is not accurate, nor is a block size of 1024 bit.
|
|
|
|
virtual unsigned int MaxBlockSize() const
|
|
|
|
{ return MAX_BLOCKSIZE; }
|
|
|
|
|
|
|
|
//! Provides the initialization vector length of the cipher
|
|
|
|
//! \return the initialization vector length, in bytes
|
|
|
|
//! \details The sematics of IVSize() is return IV_LENGTH if the default blocksize is
|
|
|
|
//! in effect. If the blocksize has changed, then the default implentation returns the value of
|
|
|
|
//! the BlockSize() parameter used during SetKey().
|
|
|
|
//! \details Derived classes may override the behavior such that a different value is returned.
|
|
|
|
//! This may happen with a cipher that requires an IV that is twice the block size.
|
|
|
|
virtual unsigned int IVSize() const =0;
|
|
|
|
|
|
|
|
//! \brief Provides the minimum size of an IV
|
|
|
|
//! \return minimal length of IVs accepted by this cipher, in bytes
|
|
|
|
virtual unsigned int MinIVLength() const
|
|
|
|
{ return MIN_BLOCKSIZE; }
|
|
|
|
|
|
|
|
//! \brief Provides the maximum size of an IV
|
|
|
|
//! \return maximal length of IVs accepted by this cipher, in bytes
|
|
|
|
virtual unsigned int MaxIVLength() const
|
|
|
|
{ return MAX_BLOCKSIZE; }
|
|
|
|
};
|
|
|
|
|
2015-11-05 06:59:46 +00:00
|
|
|
// ************** key length ***************
|
|
|
|
|
|
|
|
//! \class FixedKeyLength
|
|
|
|
//! \brief Inherited by keyed algorithms with fixed key length
|
|
|
|
//! \tparam N Default key length, in bytes
|
2015-12-17 06:37:01 +00:00
|
|
|
//! \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
|
|
|
|
//! \tparam IV_L default IV length, in bytes
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \sa SimpleKeyingInterface
|
2015-11-05 06:59:46 +00:00
|
|
|
template <unsigned int N, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
|
|
|
|
class FixedKeyLength
|
|
|
|
{
|
|
|
|
public:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(KEYLENGTH=N)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The minimum key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details MIN_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The maximum key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details MAX_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(MAX_KEYLENGTH=N)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details DEFAULT_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=N)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default IV requirements for the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
|
2015-11-05 06:59:46 +00:00
|
|
|
//! in cryptlib.h for allowed values.
|
|
|
|
CRYPTOPP_CONSTANT(IV_REQUIREMENT = IV_REQ)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default IV length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(IV_LENGTH = IV_L)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default key length for the algorithm provided by a static function.
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \param keylength the size of the key, in bytes
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details The default implementation returns KEYLENGTH. keylength is unused
|
2015-11-05 06:59:46 +00:00
|
|
|
//! in the default implementation.
|
2016-11-13 16:50:34 +00:00
|
|
|
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
|
2016-09-07 13:32:06 +00:00
|
|
|
{
|
|
|
|
return CRYPTOPP_UNUSED(keylength), static_cast<size_t>(KEYLENGTH);
|
|
|
|
}
|
2015-11-05 06:59:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//! \class VariableKeyLength
|
|
|
|
//! \brief Inherited by keyed algorithms with variable key length
|
|
|
|
//! \tparam D Default key length, in bytes
|
|
|
|
//! \tparam N Minimum key length, in bytes
|
|
|
|
//! \tparam M Maximum key length, in bytes
|
2016-11-17 14:16:09 +00:00
|
|
|
//! \tparam Q Default key length multiple, in bytes. The default multiple is 1.
|
2015-12-17 06:37:01 +00:00
|
|
|
//! \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
|
|
|
|
//! \tparam IV_L default IV length, in bytes. The default length is 0.
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \sa SimpleKeyingInterface
|
2015-11-05 06:59:46 +00:00
|
|
|
template <unsigned int D, unsigned int N, unsigned int M, unsigned int Q = 1, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
|
|
|
|
class VariableKeyLength
|
|
|
|
{
|
|
|
|
// Make these private to avoid Doxygen documenting them in all derived classes
|
|
|
|
CRYPTOPP_COMPILE_ASSERT(Q > 0);
|
|
|
|
CRYPTOPP_COMPILE_ASSERT(N % Q == 0);
|
|
|
|
CRYPTOPP_COMPILE_ASSERT(M % Q == 0);
|
|
|
|
CRYPTOPP_COMPILE_ASSERT(N < M);
|
|
|
|
CRYPTOPP_COMPILE_ASSERT(D >= N);
|
|
|
|
CRYPTOPP_COMPILE_ASSERT(M >= D);
|
|
|
|
|
|
|
|
public:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The minimum key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details MIN_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(MIN_KEYLENGTH=N)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The maximum key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details MAX_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(MAX_KEYLENGTH=M)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details DEFAULT_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=D)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The key length multiple used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details MAX_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(KEYLENGTH_MULTIPLE=Q)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default IV requirements for the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
|
2015-11-05 06:59:46 +00:00
|
|
|
//! in cryptlib.h for allowed values.
|
|
|
|
CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default initialization vector length for the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(IV_LENGTH=IV_L)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief Provides a valid key length for the algorithm provided by a static function.
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \param keylength the size of the key, in bytes
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details If keylength is less than MIN_KEYLENGTH, then the function returns
|
|
|
|
//! MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function
|
|
|
|
//! returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE,
|
|
|
|
//! then keylength is returned. Otherwise, the function returns keylength rounded
|
|
|
|
//! \a down to the next smaller multiple of KEYLENGTH_MULTIPLE.
|
|
|
|
//! \details keylength is provided in bytes, not bits.
|
2016-11-15 09:15:17 +00:00
|
|
|
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
|
2015-11-05 06:59:46 +00:00
|
|
|
{
|
2016-11-15 09:15:17 +00:00
|
|
|
return (keylength <= N) ? N :
|
|
|
|
(keylength >= M) ? M :
|
|
|
|
(keylength+Q-1) - (keylength+Q-1)%Q;
|
2015-11-05 06:59:46 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
//! \class SameKeyLengthAs
|
|
|
|
//! \brief Provides key lengths based on another class's key length
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \tparam T another FixedKeyLength or VariableKeyLength class
|
2015-12-17 06:37:01 +00:00
|
|
|
//! \tparam IV_REQ the \ref SimpleKeyingInterface::IV_Requirement "IV requirements"
|
|
|
|
//! \tparam IV_L default IV length, in bytes
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \sa SimpleKeyingInterface
|
2015-11-05 06:59:46 +00:00
|
|
|
template <class T, unsigned int IV_REQ = SimpleKeyingInterface::NOT_RESYNCHRONIZABLE, unsigned int IV_L = 0>
|
|
|
|
class SameKeyLengthAs
|
|
|
|
{
|
|
|
|
public:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The minimum key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details MIN_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(MIN_KEYLENGTH=T::MIN_KEYLENGTH)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The maximum key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details MIN_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(MAX_KEYLENGTH=T::MAX_KEYLENGTH)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default key length used by the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details MIN_KEYLENGTH is provided in bytes, not bits
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(DEFAULT_KEYLENGTH=T::DEFAULT_KEYLENGTH)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default IV requirements for the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
|
2015-11-05 06:59:46 +00:00
|
|
|
//! in cryptlib.h for allowed values.
|
|
|
|
CRYPTOPP_CONSTANT(IV_REQUIREMENT=IV_REQ)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default initialization vector length for the algorithm provided as a constant
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details IV_LENGTH is provided in bytes, not bits. The default implementation uses 0.
|
2015-11-05 06:59:46 +00:00
|
|
|
CRYPTOPP_CONSTANT(IV_LENGTH=IV_L)
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief Provides a valid key length for the algorithm provided by a static function.
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \param keylength the size of the key, in bytes
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details If keylength is less than MIN_KEYLENGTH, then the function returns
|
|
|
|
//! MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH, then the function
|
|
|
|
//! returns MAX_KEYLENGTH. If keylength is a multiple of KEYLENGTH_MULTIPLE,
|
|
|
|
//! then keylength is returned. Otherwise, the function returns keylength rounded
|
|
|
|
//! \a down to the next smaller multiple of KEYLENGTH_MULTIPLE.
|
|
|
|
//! \details keylength is provided in bytes, not bits.
|
2016-11-13 16:50:34 +00:00
|
|
|
CRYPTOPP_STATIC_CONSTEXPR size_t CRYPTOPP_API StaticGetValidKeyLength(size_t keylength)
|
2015-11-05 06:59:46 +00:00
|
|
|
{return T::StaticGetValidKeyLength(keylength);}
|
|
|
|
};
|
|
|
|
|
2015-12-14 04:53:50 +00:00
|
|
|
// ************** implementation helper for SimpleKeyingInterface ***************
|
2015-11-05 06:59:46 +00:00
|
|
|
|
|
|
|
//! \class SimpleKeyingInterfaceImpl
|
2015-12-17 06:37:01 +00:00
|
|
|
//! \brief Provides a base implementation of SimpleKeyingInterface
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \tparam BASE a SimpleKeyingInterface derived class
|
|
|
|
//! \tparam INFO a SimpleKeyingInterface derived class
|
2016-09-05 08:36:08 +00:00
|
|
|
//! \details SimpleKeyingInterfaceImpl() provides a default implementation for ciphers providing a keying interface.
|
2016-09-05 17:57:33 +00:00
|
|
|
//! Functions are virtual and not eligible for C++11 <tt>constexpr</tt>-ness.
|
2016-09-05 08:36:08 +00:00
|
|
|
//! \sa Algorithm(), SimpleKeyingInterface()
|
2015-11-05 06:59:46 +00:00
|
|
|
template <class BASE, class INFO = BASE>
|
|
|
|
class CRYPTOPP_NO_VTABLE SimpleKeyingInterfaceImpl : public BASE
|
|
|
|
{
|
|
|
|
public:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The minimum key length used by the algorithm
|
|
|
|
//! \returns minimum key length used by the algorithm, in bytes
|
2016-09-05 08:36:08 +00:00
|
|
|
size_t MinKeyLength() const
|
2015-11-05 06:59:46 +00:00
|
|
|
{return INFO::MIN_KEYLENGTH;}
|
|
|
|
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The maximum key length used by the algorithm
|
|
|
|
//! \returns maximum key length used by the algorithm, in bytes
|
2016-09-05 08:36:08 +00:00
|
|
|
size_t MaxKeyLength() const
|
2015-11-05 06:59:46 +00:00
|
|
|
{return (size_t)INFO::MAX_KEYLENGTH;}
|
2016-09-05 07:13:45 +00:00
|
|
|
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default key length used by the algorithm
|
|
|
|
//! \returns default key length used by the algorithm, in bytes
|
2016-09-05 08:36:08 +00:00
|
|
|
size_t DefaultKeyLength() const
|
2015-11-05 06:59:46 +00:00
|
|
|
{return INFO::DEFAULT_KEYLENGTH;}
|
2016-09-05 07:13:45 +00:00
|
|
|
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief Provides a valid key length for the algorithm
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \param keylength the size of the key, in bytes
|
2016-10-11 23:51:15 +00:00
|
|
|
//! \returns the valid key length, in bytes
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details keylength is provided in bytes, not bits. If keylength is less than MIN_KEYLENGTH,
|
|
|
|
//! then the function returns MIN_KEYLENGTH. If keylength is greater than MAX_KEYLENGTH,
|
|
|
|
//! then the function returns MAX_KEYLENGTH. if If keylength is a multiple of KEYLENGTH_MULTIPLE,
|
|
|
|
//! then keylength is returned. Otherwise, the function returns a \a lower multiple of
|
|
|
|
//! KEYLENGTH_MULTIPLE.
|
2016-09-05 08:36:08 +00:00
|
|
|
size_t GetValidKeyLength(size_t keylength) const {return INFO::StaticGetValidKeyLength(keylength);}
|
2015-11-05 06:59:46 +00:00
|
|
|
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default IV requirements for the algorithm
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details The default value is NOT_RESYNCHRONIZABLE. See IV_Requirement
|
2015-11-05 06:59:46 +00:00
|
|
|
//! in cryptlib.h for allowed values.
|
2016-09-05 08:36:08 +00:00
|
|
|
SimpleKeyingInterface::IV_Requirement IVRequirement() const
|
2015-11-05 06:59:46 +00:00
|
|
|
{return (SimpleKeyingInterface::IV_Requirement)INFO::IV_REQUIREMENT;}
|
2016-09-05 07:13:45 +00:00
|
|
|
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \brief The default initialization vector length for the algorithm
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details IVSize is provided in bytes, not bits. The default implementation uses IV_LENGTH, which is 0.
|
2016-09-05 08:36:08 +00:00
|
|
|
unsigned int IVSize() const
|
2015-11-05 06:59:46 +00:00
|
|
|
{return INFO::IV_LENGTH;}
|
|
|
|
};
|
|
|
|
|
|
|
|
//! \class BlockCipherImpl
|
2015-12-17 06:37:01 +00:00
|
|
|
//! \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for block ciphers
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \tparam INFO a SimpleKeyingInterface derived class
|
|
|
|
//! \tparam BASE a SimpleKeyingInterface derived class
|
2016-09-05 08:36:08 +00:00
|
|
|
//! \details BlockCipherImpl() provides a default implementation for block ciphers using AlgorithmImpl()
|
2016-09-05 17:57:33 +00:00
|
|
|
//! and SimpleKeyingInterfaceImpl(). Functions are virtual and not eligible for C++11 <tt>constexpr</tt>-ness.
|
2016-09-05 08:36:08 +00:00
|
|
|
//! \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl()
|
2015-11-05 06:59:46 +00:00
|
|
|
template <class INFO, class BASE = BlockCipher>
|
|
|
|
class CRYPTOPP_NO_VTABLE BlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
|
|
|
|
{
|
|
|
|
public:
|
2015-12-14 04:53:50 +00:00
|
|
|
//! Provides the block size of the algorithm
|
|
|
|
//! \returns the block size of the algorithm, in bytes
|
2015-11-05 06:59:46 +00:00
|
|
|
unsigned int BlockSize() const {return this->BLOCKSIZE;}
|
|
|
|
};
|
|
|
|
|
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
|
|
|
//! \class VariableBlockCipherImpl
|
|
|
|
//! \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for block ciphers with varibale block sizes
|
|
|
|
//! \tparam INFO a SimpleKeyingInterface derived class
|
|
|
|
//! \tparam BASE a SimpleKeyingInterface derived class
|
|
|
|
//! \details VariableBlockCipherImpl() provides a default implementation for block ciphers with varibale block sizes using AlgorithmImpl()
|
|
|
|
//! and SimpleKeyingInterfaceImpl().
|
|
|
|
//! \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl()
|
|
|
|
template <class INFO, class BASE = BlockCipher>
|
|
|
|
class CRYPTOPP_NO_VTABLE VariableBlockCipherImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<TwoBases<BASE, INFO> > >
|
|
|
|
{
|
|
|
|
public:
|
2017-05-04 01:06:49 +00:00
|
|
|
VariableBlockCipherImpl() : m_blocksize(0), m_ivlength(0) {}
|
|
|
|
VariableBlockCipherImpl(unsigned int blockSize) : m_blocksize(blockSize), m_ivlength(blockSize) {}
|
2017-05-04 02:34:37 +00:00
|
|
|
VariableBlockCipherImpl(unsigned int blockSize, unsigned int ivLength) : m_blocksize(blockSize), m_ivlength(ivLength) {}
|
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
|
|
|
|
|
|
|
//! Provides the block size of the algorithm
|
|
|
|
//! \returns the block size, in bytes
|
|
|
|
unsigned int BlockSize() const {
|
2017-05-04 01:06:49 +00:00
|
|
|
return m_blocksize ? m_blocksize : this->DEFAULT_BLOCKSIZE;
|
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
|
|
|
}
|
|
|
|
|
|
|
|
//! Provides the initialization vector length of the algorithm
|
|
|
|
//! \returns the initialization vector length, in bytes
|
|
|
|
unsigned int IVSize() const {
|
|
|
|
if (!this->IsResynchronizable())
|
2017-05-01 20:56:21 +00:00
|
|
|
throw NotImplemented(this->GetAlgorithm().AlgorithmName() + ": this object doesn't support resynchronization");
|
2017-05-04 01:06:49 +00:00
|
|
|
return m_ivlength ? m_ivlength : this->IV_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
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2017-05-04 01:06:49 +00:00
|
|
|
unsigned int m_blocksize, m_ivlength;
|
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
|
|
|
};
|
|
|
|
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \class BlockCipherFinal
|
|
|
|
//! \brief Provides class member functions to key a block cipher
|
|
|
|
//! \tparam DIR a CipherDir
|
|
|
|
//! \tparam BASE a BlockCipherImpl derived class
|
|
|
|
template <CipherDir DIR, class BASE>
|
|
|
|
class BlockCipherFinal : public ClonableImpl<BlockCipherFinal<DIR, BASE>, BASE>
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
//! \brief Construct a default BlockCipherFinal
|
|
|
|
//! \details The cipher is not keyed.
|
|
|
|
BlockCipherFinal() {}
|
2015-11-18 20:32:28 +00:00
|
|
|
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \brief Construct a BlockCipherFinal
|
|
|
|
//! \param key a byte array used to key the cipher
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
|
|
|
|
//! SimpleKeyingInterface::SetKey.
|
2015-11-05 06:59:46 +00:00
|
|
|
BlockCipherFinal(const byte *key)
|
|
|
|
{this->SetKey(key, this->DEFAULT_KEYLENGTH);}
|
2016-09-05 07:13:45 +00:00
|
|
|
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \brief Construct a BlockCipherFinal
|
|
|
|
//! \param key a byte array used to key the cipher
|
|
|
|
//! \param length the length of the byte array
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
|
|
|
|
//! SimpleKeyingInterface::SetKey.
|
2015-11-05 06:59:46 +00:00
|
|
|
BlockCipherFinal(const byte *key, size_t length)
|
|
|
|
{this->SetKey(key, length);}
|
2016-09-05 07:13:45 +00:00
|
|
|
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \brief Construct a BlockCipherFinal
|
|
|
|
//! \param key a byte array used to key the cipher
|
|
|
|
//! \param length the length of the byte array
|
|
|
|
//! \param rounds the number of rounds
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
|
|
|
|
//! SimpleKeyingInterface::SetKeyWithRounds.
|
2015-11-05 06:59:46 +00:00
|
|
|
BlockCipherFinal(const byte *key, size_t length, unsigned int rounds)
|
|
|
|
{this->SetKeyWithRounds(key, length, rounds);}
|
|
|
|
|
|
|
|
//! \brief Provides the direction of the cipher
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \returns true if DIR is ENCRYPTION, false otherwise
|
2015-12-17 06:37:01 +00:00
|
|
|
//! \sa GetCipherDirection(), IsPermutation()
|
2016-09-05 08:36:08 +00:00
|
|
|
bool IsForwardTransformation() const {return DIR == ENCRYPTION;}
|
2015-11-05 06:59:46 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
//! \class MessageAuthenticationCodeImpl
|
2015-12-17 06:37:01 +00:00
|
|
|
//! \brief Provides a base implementation of Algorithm and SimpleKeyingInterface for message authentication codes
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \tparam INFO a SimpleKeyingInterface derived class
|
|
|
|
//! \tparam BASE a SimpleKeyingInterface derived class
|
2016-09-05 08:36:08 +00:00
|
|
|
//! \details MessageAuthenticationCodeImpl() provides a default implementation for message authentication codes
|
|
|
|
//! using AlgorithmImpl() and SimpleKeyingInterfaceImpl(). Functions are virtual and not subject to C++11
|
|
|
|
//! <tt>constexpr</tt>.
|
|
|
|
//! \sa Algorithm(), SimpleKeyingInterface(), AlgorithmImpl(), SimpleKeyingInterfaceImpl()
|
2015-11-05 06:59:46 +00:00
|
|
|
template <class BASE, class INFO = BASE>
|
|
|
|
class MessageAuthenticationCodeImpl : public AlgorithmImpl<SimpleKeyingInterfaceImpl<BASE, INFO>, INFO>
|
|
|
|
{
|
|
|
|
};
|
|
|
|
|
|
|
|
//! \class MessageAuthenticationCodeFinal
|
|
|
|
//! \brief Provides class member functions to key a message authentication code
|
|
|
|
//! \tparam BASE a BlockCipherImpl derived class
|
2017-07-27 23:15:21 +00:00
|
|
|
//! \details A default implementation for MessageAuthenticationCode
|
2015-11-05 06:59:46 +00:00
|
|
|
template <class BASE>
|
|
|
|
class MessageAuthenticationCodeFinal : public ClonableImpl<MessageAuthenticationCodeFinal<BASE>, MessageAuthenticationCodeImpl<BASE> >
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
//! \brief Construct a default MessageAuthenticationCodeFinal
|
|
|
|
//! \details The message authentication code is not keyed.
|
|
|
|
MessageAuthenticationCodeFinal() {}
|
|
|
|
//! \brief Construct a BlockCipherFinal
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \param key a byte array used to key the algorithm
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
|
|
|
|
//! SimpleKeyingInterface::SetKey.
|
2015-11-05 06:59:46 +00:00
|
|
|
MessageAuthenticationCodeFinal(const byte *key)
|
|
|
|
{this->SetKey(key, this->DEFAULT_KEYLENGTH);}
|
|
|
|
//! \brief Construct a BlockCipherFinal
|
2015-12-14 04:53:50 +00:00
|
|
|
//! \param key a byte array used to key the algorithm
|
2015-11-05 06:59:46 +00:00
|
|
|
//! \param length the length of the byte array
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \details key must be at least DEFAULT_KEYLENGTH in length. Internally, the function calls
|
|
|
|
//! SimpleKeyingInterface::SetKey.
|
2015-11-05 06:59:46 +00:00
|
|
|
MessageAuthenticationCodeFinal(const byte *key, size_t length)
|
|
|
|
{this->SetKey(key, length);}
|
|
|
|
};
|
|
|
|
|
|
|
|
// ************** documentation ***************
|
|
|
|
|
|
|
|
//! \class BlockCipherDocumentation
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \brief Provides Encryption and Decryption typedefs used by derived classes to
|
2015-11-05 06:59:46 +00:00
|
|
|
//! implement a block cipher
|
|
|
|
//! \details These objects usually should not be used directly. See CipherModeDocumentation
|
2016-09-05 07:13:45 +00:00
|
|
|
//! instead. Each class derived from this one defines two types, Encryption and Decryption,
|
2015-11-05 06:59:46 +00:00
|
|
|
//! both of which implement the BlockCipher interface.
|
|
|
|
struct BlockCipherDocumentation
|
|
|
|
{
|
|
|
|
//! implements the BlockCipher interface
|
|
|
|
typedef BlockCipher Encryption;
|
|
|
|
//! implements the BlockCipher interface
|
|
|
|
typedef BlockCipher Decryption;
|
|
|
|
};
|
|
|
|
|
|
|
|
//! \class SymmetricCipherDocumentation
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \brief Provides Encryption and Decryption typedefs used by derived classes to
|
2015-11-05 06:59:46 +00:00
|
|
|
//! implement a symmetric cipher
|
2016-09-05 07:13:45 +00:00
|
|
|
//! \details Each class derived from this one defines two types, Encryption and Decryption,
|
2015-11-05 06:59:46 +00:00
|
|
|
//! both of which implement the SymmetricCipher interface. Two types of classes derive
|
|
|
|
//! from this class: stream ciphers and block cipher modes. Stream ciphers can be used
|
|
|
|
//! alone, cipher mode classes need to be used with a block cipher. See CipherModeDocumentation
|
|
|
|
//! for more for information about using cipher modes and block ciphers.
|
|
|
|
struct SymmetricCipherDocumentation
|
|
|
|
{
|
|
|
|
//! implements the SymmetricCipher interface
|
|
|
|
typedef SymmetricCipher Encryption;
|
|
|
|
//! implements the SymmetricCipher interface
|
|
|
|
typedef SymmetricCipher Decryption;
|
|
|
|
};
|
|
|
|
|
|
|
|
//! \class AuthenticatedSymmetricCipherDocumentation
|
2015-11-18 20:32:28 +00:00
|
|
|
//! \brief Provides Encryption and Decryption typedefs used by derived classes to
|
2015-11-05 06:59:46 +00:00
|
|
|
//! implement an authenticated encryption cipher
|
2016-09-05 07:13:45 +00:00
|
|
|
//! \details Each class derived from this one defines two types, Encryption and Decryption,
|
2015-11-05 06:59:46 +00:00
|
|
|
//! both of which implement the AuthenticatedSymmetricCipher interface.
|
|
|
|
struct AuthenticatedSymmetricCipherDocumentation
|
|
|
|
{
|
|
|
|
//! implements the AuthenticatedSymmetricCipher interface
|
|
|
|
typedef AuthenticatedSymmetricCipher Encryption;
|
|
|
|
//! implements the AuthenticatedSymmetricCipher interface
|
|
|
|
typedef AuthenticatedSymmetricCipher Decryption;
|
|
|
|
};
|
|
|
|
|
|
|
|
NAMESPACE_END
|
2016-09-05 07:13:45 +00:00
|
|
|
|
2015-11-05 06:59:46 +00:00
|
|
|
#if CRYPTOPP_MSC_VERSION
|
2015-12-17 06:39:13 +00:00
|
|
|
# pragma warning(pop)
|
2015-11-05 06:59:46 +00:00
|
|
|
#endif
|
|
|
|
|
2016-12-02 19:47:31 +00:00
|
|
|
// Issue 340
|
|
|
|
#if CRYPTOPP_GCC_DIAGNOSTIC_AVAILABLE
|
|
|
|
# pragma GCC diagnostic pop
|
|
|
|
#endif
|
|
|
|
|
2015-11-05 06:59:46 +00:00
|
|
|
#endif
|