summaryrefslogtreecommitdiff
path: root/external/crypto++-5.6.3/cmac.cpp
diff options
context:
space:
mode:
authorFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
committerFluorescentCIAAfricanAmerican <[email protected]>2020-04-22 12:56:21 -0400
commit3bf9df6b2785fa6d951086978a3e66f49427166a (patch)
tree2c0f1f0c63c4832882bc93814ebd2c2b1c6224e5 /external/crypto++-5.6.3/cmac.cpp
downloadarchived-source-engine-2018-hl2-src-master.tar.xz
archived-source-engine-2018-hl2-src-master.zip
Diffstat (limited to 'external/crypto++-5.6.3/cmac.cpp')
-rw-r--r--external/crypto++-5.6.3/cmac.cpp126
1 files changed, 126 insertions, 0 deletions
diff --git a/external/crypto++-5.6.3/cmac.cpp b/external/crypto++-5.6.3/cmac.cpp
new file mode 100644
index 0000000..62ae6c9
--- /dev/null
+++ b/external/crypto++-5.6.3/cmac.cpp
@@ -0,0 +1,126 @@
+// 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 &params)
+{
+ 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)
+{
+ assert((input && length) || !(input || length));
+ if (!length)
+ return;
+
+ BlockCipher &cipher = AccessCipher();
+ unsigned int blockSize = cipher.BlockSize();
+
+ if (m_counter > 0)
+ {
+ const unsigned int len = UnsignedMin(blockSize - m_counter, length);
+ if (len)
+ {
+ 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