Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/cmac.cpp
2 views
// cmac.cpp - originally written and placed in the public domain by Wei Dai12#include "pch.h"34#ifndef CRYPTOPP_IMPORTS56#include "cmac.h"7#include "misc.h"89ANONYMOUS_NAMESPACE_BEGIN1011using CryptoPP::byte;12using CryptoPP::IsPowerOf2;1314void MulU(byte *k, unsigned int len)15{16byte carry = 0;17for (int i=len-1; i>=1; i-=2)18{19byte carry2 = k[i] >> 7;20k[i] += k[i] + carry;21carry = k[i-1] >> 7;22k[i-1] += k[i-1] + carry2;23}2425#ifndef CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS26CRYPTOPP_ASSERT(len == 16);2728if (carry)29{30k[15] ^= 0x87;31return;32}33#else34CRYPTOPP_ASSERT(IsPowerOf2(len));35CRYPTOPP_ASSERT(len >= 8);36CRYPTOPP_ASSERT(len <= 128);3738if (carry)39{40switch (len)41{42case 8:43k[7] ^= 0x1b;44break;45case 16:46k[15] ^= 0x87;47break;48case 32:49// https://crypto.stackexchange.com/q/9815/1049650// Polynomial x^256 + x^10 + x^5 + x^2 + 151k[30] ^= 4;52k[31] ^= 0x25;53break;54case 64:55// https://crypto.stackexchange.com/q/9815/1049656// Polynomial x^512 + x^8 + x^5 + x^2 + 157k[62] ^= 1;58k[63] ^= 0x25;59break;60case 128:61// https://crypto.stackexchange.com/q/9815/1049662// Polynomial x^1024 + x^19 + x^6 + x + 163k[125] ^= 8;64k[126] ^= 0x00;65k[127] ^= 0x43;66break;67default:68CRYPTOPP_ASSERT(0);69}70}71#endif // CRYPTOPP_CMAC_WIDE_BLOCK_CIPHERS72}7374ANONYMOUS_NAMESPACE_END7576NAMESPACE_BEGIN(CryptoPP)7778void CMAC_Base::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs ¶ms)79{80BlockCipher &cipher = AccessCipher();81cipher.SetKey(key, length, params);8283unsigned int blockSize = cipher.BlockSize();84m_reg.CleanNew(3*blockSize);85m_counter = 0;8687cipher.ProcessBlock(m_reg, m_reg+blockSize);88MulU(m_reg+blockSize, blockSize);89std::memcpy(m_reg+2*blockSize, m_reg+blockSize, blockSize);90MulU(m_reg+2*blockSize, blockSize);91}9293void CMAC_Base::Update(const byte *input, size_t length)94{95CRYPTOPP_ASSERT((input && length) || !(input || length));96if (!length)97return;9899BlockCipher &cipher = AccessCipher();100unsigned int blockSize = cipher.BlockSize();101102if (m_counter > 0)103{104const unsigned int len = UnsignedMin(blockSize - m_counter, length);105if (len)106{107xorbuf(m_reg+m_counter, input, len);108length -= len;109input += len;110m_counter += len;111}112113if (m_counter == blockSize && length > 0)114{115cipher.ProcessBlock(m_reg);116m_counter = 0;117}118}119120if (length > blockSize)121{122CRYPTOPP_ASSERT(m_counter == 0);123size_t leftOver = 1 + cipher.AdvancedProcessBlocks(m_reg, input, m_reg, length-1, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);124input += (length - leftOver);125length = leftOver;126}127128if (length > 0)129{130CRYPTOPP_ASSERT(m_counter + length <= blockSize);131xorbuf(m_reg+m_counter, input, length);132m_counter += (unsigned int)length;133}134135CRYPTOPP_ASSERT(m_counter > 0);136}137138void CMAC_Base::TruncatedFinal(byte *mac, size_t size)139{140ThrowIfInvalidTruncatedSize(size);141142BlockCipher &cipher = AccessCipher();143unsigned int blockSize = cipher.BlockSize();144145if (m_counter < blockSize)146{147m_reg[m_counter] ^= 0x80;148cipher.AdvancedProcessBlocks(m_reg, m_reg+2*blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);149}150else151cipher.AdvancedProcessBlocks(m_reg, m_reg+blockSize, m_reg, blockSize, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);152153// UBsan finding154if (mac)155std::memcpy(mac, m_reg, size);156157m_counter = 0;158std::memset(m_reg, 0, blockSize);159}160161NAMESPACE_END162163#endif164165166