Convert GCM to use runtime blocksize checking (Issue 408)
GCM is still only defined for 16-byte ciphers, but this is where we need to be when we add the larger polynomialspull/461/head
parent
f5aa6f1f06
commit
7d21cdd54e
25
gcm.cpp
25
gcm.cpp
|
|
@ -325,7 +325,13 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
|
||||||
BlockCipher &blockCipher = AccessBlockCipher();
|
BlockCipher &blockCipher = AccessBlockCipher();
|
||||||
blockCipher.SetKey(userKey, keylength, params);
|
blockCipher.SetKey(userKey, keylength, params);
|
||||||
|
|
||||||
if (blockCipher.BlockSize() != REQUIRED_BLOCKSIZE)
|
// GCM is only defined for 16-byte block ciphers at the moment.
|
||||||
|
// However, variable blocksize support means we have to defer
|
||||||
|
// blocksize checks to runtime after the key is set. Also see
|
||||||
|
// https://github.com/weidai11/cryptopp/issues/408.
|
||||||
|
const unsigned int blockSize = blockCipher.BlockSize();
|
||||||
|
CRYPTOPP_ASSERT(blockSize == REQUIRED_BLOCKSIZE);
|
||||||
|
if (blockSize != REQUIRED_BLOCKSIZE)
|
||||||
throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16");
|
throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16");
|
||||||
|
|
||||||
int tableSize, i, j, k;
|
int tableSize, i, j, k;
|
||||||
|
|
@ -335,7 +341,7 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
|
||||||
{
|
{
|
||||||
// Avoid "parameter not used" error and suppress Coverity finding
|
// Avoid "parameter not used" error and suppress Coverity finding
|
||||||
(void)params.GetIntValue(Name::TableSize(), tableSize);
|
(void)params.GetIntValue(Name::TableSize(), tableSize);
|
||||||
tableSize = s_clmulTableSizeInBlocks * REQUIRED_BLOCKSIZE;
|
tableSize = s_clmulTableSizeInBlocks * blockSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#elif CRYPTOPP_BOOL_ARM_PMULL_AVAILABLE
|
#elif CRYPTOPP_BOOL_ARM_PMULL_AVAILABLE
|
||||||
|
|
@ -343,7 +349,7 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
|
||||||
{
|
{
|
||||||
// Avoid "parameter not used" error and suppress Coverity finding
|
// Avoid "parameter not used" error and suppress Coverity finding
|
||||||
(void)params.GetIntValue(Name::TableSize(), tableSize);
|
(void)params.GetIntValue(Name::TableSize(), tableSize);
|
||||||
tableSize = s_clmulTableSizeInBlocks * REQUIRED_BLOCKSIZE;
|
tableSize = s_clmulTableSizeInBlocks * blockSize;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -359,10 +365,10 @@ void GCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
m_buffer.resize(3*REQUIRED_BLOCKSIZE + tableSize);
|
m_buffer.resize(3*blockSize + tableSize);
|
||||||
byte *table = MulTable();
|
byte *table = MulTable();
|
||||||
byte *hashKey = HashKey();
|
byte *hashKey = HashKey();
|
||||||
memset(hashKey, 0, REQUIRED_BLOCKSIZE);
|
memset(hashKey, 0, blockSize);
|
||||||
blockCipher.ProcessBlock(hashKey);
|
blockCipher.ProcessBlock(hashKey);
|
||||||
|
|
||||||
#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
|
#if CRYPTOPP_BOOL_AESNI_INTRINSICS_AVAILABLE
|
||||||
|
|
@ -537,6 +543,13 @@ void GCM_Base::Resync(const byte *iv, size_t len)
|
||||||
BlockCipher &cipher = AccessBlockCipher();
|
BlockCipher &cipher = AccessBlockCipher();
|
||||||
byte *hashBuffer = HashBuffer();
|
byte *hashBuffer = HashBuffer();
|
||||||
|
|
||||||
|
// GCM is only defined for 16-byte block ciphers at the moment.
|
||||||
|
// However, variable blocksize support means we have to defer
|
||||||
|
// blocksize checks to runtime after the key is set. Also see
|
||||||
|
// https://github.com/weidai11/cryptopp/issues/408.
|
||||||
|
const unsigned int blockSize = cipher.BlockSize();
|
||||||
|
CRYPTOPP_ASSERT(blockSize == REQUIRED_BLOCKSIZE);
|
||||||
|
|
||||||
if (len == 12)
|
if (len == 12)
|
||||||
{
|
{
|
||||||
memcpy(hashBuffer, iv, len);
|
memcpy(hashBuffer, iv, len);
|
||||||
|
|
@ -568,7 +581,7 @@ void GCM_Base::Resync(const byte *iv, size_t len)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_state >= State_IVSet)
|
if (m_state >= State_IVSet)
|
||||||
m_ctr.Resynchronize(hashBuffer, REQUIRED_BLOCKSIZE);
|
m_ctr.Resynchronize(hashBuffer, blockSize);
|
||||||
else
|
else
|
||||||
m_ctr.SetCipherWithIV(cipher, hashBuffer);
|
m_ctr.SetCipherWithIV(cipher, hashBuffer);
|
||||||
|
|
||||||
|
|
|
||||||
6
gcm.h
6
gcm.h
|
|
@ -74,9 +74,9 @@ protected:
|
||||||
virtual GCM_TablesOption GetTablesOption() const =0;
|
virtual GCM_TablesOption GetTablesOption() const =0;
|
||||||
|
|
||||||
const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();};
|
const BlockCipher & GetBlockCipher() const {return const_cast<GCM_Base *>(this)->AccessBlockCipher();};
|
||||||
byte *HashBuffer() {return m_buffer+REQUIRED_BLOCKSIZE;}
|
byte *HashBuffer() {return m_buffer+GetBlockCipher().BlockSize();}
|
||||||
byte *HashKey() {return m_buffer+2*REQUIRED_BLOCKSIZE;}
|
byte *HashKey() {return m_buffer+2*GetBlockCipher().BlockSize();}
|
||||||
byte *MulTable() {return m_buffer+3*REQUIRED_BLOCKSIZE;}
|
byte *MulTable() {return m_buffer+3*GetBlockCipher().BlockSize();}
|
||||||
inline void ReverseHashBufferIfNeeded();
|
inline void ReverseHashBufferIfNeeded();
|
||||||
|
|
||||||
class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption
|
class CRYPTOPP_DLL GCTR : public CTR_Mode_ExternalCipher::Encryption
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue