diff options
author | Mattes D <github@xoft.cz> | 2013-11-27 09:23:17 +0100 |
---|---|---|
committer | Mattes D <github@xoft.cz> | 2013-11-27 09:23:17 +0100 |
commit | 49760db89d94ede5d123d927141a6cd60dbaaf07 (patch) | |
tree | 6c6cf99e4cf3128311a93cd187947b502f3732a0 /lib/cryptopp/cmac.cpp | |
parent | cWorld::SpawnExperienceOrb() now returns the entity ID of the spawned orb. (diff) | |
parent | Fixed VC2008 compilation, normalized include paths. (diff) | |
download | cuberite-49760db89d94ede5d123d927141a6cd60dbaaf07.tar cuberite-49760db89d94ede5d123d927141a6cd60dbaaf07.tar.gz cuberite-49760db89d94ede5d123d927141a6cd60dbaaf07.tar.bz2 cuberite-49760db89d94ede5d123d927141a6cd60dbaaf07.tar.lz cuberite-49760db89d94ede5d123d927141a6cd60dbaaf07.tar.xz cuberite-49760db89d94ede5d123d927141a6cd60dbaaf07.tar.zst cuberite-49760db89d94ede5d123d927141a6cd60dbaaf07.zip |
Diffstat (limited to 'lib/cryptopp/cmac.cpp')
-rw-r--r-- | lib/cryptopp/cmac.cpp | 122 |
1 files changed, 122 insertions, 0 deletions
diff --git a/lib/cryptopp/cmac.cpp b/lib/cryptopp/cmac.cpp new file mode 100644 index 000000000..a31d5f8b0 --- /dev/null +++ b/lib/cryptopp/cmac.cpp @@ -0,0 +1,122 @@ +// cmac.cpp - written and placed in the public domain by Wei Dai + +#include "pch.h" + +#ifndef CRYPTOPP_IMPORTS + +#include "cmac.h" + +NAMESPACE_BEGIN(CryptoPP) + +static void MulU(byte *k, unsigned int length) +{ + byte carry = 0; + + for (int i=length-1; i>=1; i-=2) + { + byte carry2 = k[i] >> 7; + k[i] += k[i] + carry; + carry = k[i-1] >> 7; + k[i-1] += k[i-1] + carry2; + } + + if (carry) + { + switch (length) + { + case 8: + k[7] ^= 0x1b; + break; + case 16: + k[15] ^= 0x87; + break; + case 32: + k[30] ^= 4; + k[31] ^= 0x23; + break; + default: + throw InvalidArgument("CMAC: " + IntToString(length) + " is not a supported cipher block size"); + } + } +} + +void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms) +{ + BlockCipher &cipher = AccessCipher(); + unsigned int blockSize = cipher.BlockSize(); + + cipher.SetKey(key, length, params); + m_reg.CleanNew(3*blockSize); + m_counter = 0; + + cipher.ProcessBlock(m_reg, m_reg+blockSize); + MulU(m_reg+blockSize, blockSize); + memcpy(m_reg+2*blockSize, m_reg+blockSize, blockSize); + MulU(m_reg+2*blockSize, blockSize); +} + +void CMAC_Base::Update(const byte *input, size_t length) +{ + if (!length) + return; + + BlockCipher &cipher = AccessCipher(); + unsigned int blockSize = cipher.BlockSize(); + + if (m_counter > 0) + { + unsigned int len = UnsignedMin(blockSize - m_counter, length); + xorbuf(m_reg+m_counter, input, len); + length -= len; + input += len; + m_counter += len; + + if (m_counter == blockSize && length > 0) + { + cipher.ProcessBlock(m_reg); + m_counter = 0; + } + } + + if (length > blockSize) + { + assert(m_counter == 0); + size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, input, m_reg, length-1, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); + input += (length - leftOver); + length = leftOver; + } + + if (length > 0) + { + assert(m_counter + length <= blockSize); + xorbuf(m_reg+m_counter, input, length); + m_counter += (unsigned int)length; + } + + assert(m_counter > 0); +} + +void CMAC_Base::TruncatedFinal(byte *mac, size_t size) +{ + ThrowIfInvalidTruncatedSize(size); + + BlockCipher &cipher = AccessCipher(); + unsigned int blockSize = cipher.BlockSize(); + + if (m_counter < blockSize) + { + m_reg[m_counter] ^= 0x80; + cipher.AdvancedProcessBlocks(m_reg, m_reg+2*blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); + } + else + cipher.AdvancedProcessBlocks(m_reg, m_reg+blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput); + + memcpy(mac, m_reg, size); + + m_counter = 0; + memset(m_reg, 0, blockSize); +} + +NAMESPACE_END + +#endif |