Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/ccm.cpp
2 views
// ccm.cpp - originally written and placed in the public domain by Wei Dai12#include "pch.h"34#ifndef CRYPTOPP_IMPORTS56#include "ccm.h"78NAMESPACE_BEGIN(CryptoPP)910void CCM_Base::SetKeyWithoutResync(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)11{12BlockCipher &blockCipher = AccessBlockCipher();13blockCipher.SetKey(userKey, keylength, params);1415if (blockCipher.BlockSize() != REQUIRED_BLOCKSIZE)16throw InvalidArgument(AlgorithmName() + ": block size of underlying block cipher is not 16");1718m_digestSize = params.GetIntValueWithDefault(Name::DigestSize(), DefaultDigestSize());19if (m_digestSize % 2 > 0 || m_digestSize < 4 || m_digestSize > 16)20throw InvalidArgument(AlgorithmName() + ": DigestSize must be 4, 6, 8, 10, 12, 14, or 16");2122m_buffer.Grow(2*REQUIRED_BLOCKSIZE);23m_L = 8;24}2526void CCM_Base::Resync(const byte *iv, size_t len)27{28BlockCipher &cipher = AccessBlockCipher();2930m_L = REQUIRED_BLOCKSIZE-1-(int)len;31CRYPTOPP_ASSERT(m_L >= 2);32if (m_L > 8)33m_L = 8;3435m_buffer[0] = byte(m_L-1); // flag36std::memcpy(m_buffer+1, iv, len);37std::memset(m_buffer+1+len, 0, REQUIRED_BLOCKSIZE-1-len);3839if (m_state >= State_IVSet)40m_ctr.Resynchronize(m_buffer, REQUIRED_BLOCKSIZE);41else42m_ctr.SetCipherWithIV(cipher, m_buffer);4344m_ctr.Seek(REQUIRED_BLOCKSIZE);45m_aadLength = 0;46m_messageLength = 0;47}4849void CCM_Base::UncheckedSpecifyDataLengths(lword headerLength, lword messageLength, lword /*footerLength*/)50{51if (m_state != State_IVSet)52throw BadState(AlgorithmName(), "SpecifyDataLengths", "or after State_IVSet");5354m_aadLength = headerLength;55m_messageLength = messageLength;5657byte *cbcBuffer = CBC_Buffer();58const BlockCipher &cipher = GetBlockCipher();5960cbcBuffer[0] = byte(64*(headerLength>0) + 8*((m_digestSize-2)/2) + (m_L-1)); // flag61PutWord<word64>(true, BIG_ENDIAN_ORDER, cbcBuffer+REQUIRED_BLOCKSIZE-8, m_messageLength);62std::memcpy(cbcBuffer+1, m_buffer+1, REQUIRED_BLOCKSIZE-1-m_L);63cipher.ProcessBlock(cbcBuffer);6465if (headerLength>0)66{67CRYPTOPP_ASSERT(m_bufferedDataLength == 0);6869if (headerLength < ((1<<16) - (1<<8)))70{71PutWord<word16>(true, BIG_ENDIAN_ORDER, m_buffer, (word16)headerLength);72m_bufferedDataLength = 2;73}74else if (headerLength < (W64LIT(1)<<32))75{76m_buffer[0] = 0xff;77m_buffer[1] = 0xfe;78PutWord<word32>(false, BIG_ENDIAN_ORDER, m_buffer+2, (word32)headerLength);79m_bufferedDataLength = 6;80}81else82{83m_buffer[0] = 0xff;84m_buffer[1] = 0xff;85PutWord<word64>(false, BIG_ENDIAN_ORDER, m_buffer+2, headerLength);86m_bufferedDataLength = 10;87}88}89}9091size_t CCM_Base::AuthenticateBlocks(const byte *data, size_t len)92{93byte *cbcBuffer = CBC_Buffer();94const BlockCipher &cipher = GetBlockCipher();95return cipher.AdvancedProcessBlocks(cbcBuffer, data, cbcBuffer, len, BlockTransformation::BT_DontIncrementInOutPointers|BlockTransformation::BT_XorInput);96}9798void CCM_Base::AuthenticateLastHeaderBlock()99{100byte *cbcBuffer = CBC_Buffer();101const BlockCipher &cipher = GetBlockCipher();102103if (m_aadLength != m_totalHeaderLength)104throw InvalidArgument(AlgorithmName() + ": header length doesn't match that given in SpecifyDataLengths");105106if (m_bufferedDataLength > 0)107{108xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength);109cipher.ProcessBlock(cbcBuffer);110m_bufferedDataLength = 0;111}112}113114void CCM_Base::AuthenticateLastConfidentialBlock()115{116byte *cbcBuffer = CBC_Buffer();117const BlockCipher &cipher = GetBlockCipher();118119if (m_messageLength != m_totalMessageLength)120throw InvalidArgument(AlgorithmName() + ": message length doesn't match that given in SpecifyDataLengths");121122if (m_bufferedDataLength > 0)123{124xorbuf(cbcBuffer, m_buffer, m_bufferedDataLength);125cipher.ProcessBlock(cbcBuffer);126m_bufferedDataLength = 0;127}128}129130void CCM_Base::AuthenticateLastFooterBlock(byte *mac, size_t macSize)131{132m_ctr.Seek(0);133m_ctr.ProcessData(mac, CBC_Buffer(), macSize);134}135136NAMESPACE_END137138#endif139140141