Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/authenc.cpp
2 views
// authenc.cpp - originally written and placed in the public domain by Wei Dai12#include "pch.h"34#ifndef CRYPTOPP_IMPORTS56#include "authenc.h"78NAMESPACE_BEGIN(CryptoPP)910void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_t len)11{12// UBsan finding with -std=c++03 using memcpy13CRYPTOPP_ASSERT(input && len);14if(!input || !len) return;1516unsigned int blockSize = AuthenticationBlockSize();17unsigned int &num = m_bufferedDataLength;18byte* data = m_buffer.begin();1920if (data && num) // process left over data21{22if (num+len >= blockSize)23{24std::memcpy(data+num, input, blockSize-num);25AuthenticateBlocks(data, blockSize);26input += (blockSize-num);27len -= (blockSize-num);28num = 0;29// drop through and do the rest30}31else32{33std::memcpy(data+num, input, len);34num += (unsigned int)len;35return;36}37}3839// now process the input data in blocks of blockSize bytes and save the leftovers to m_data40if (len >= blockSize)41{42size_t leftOver = AuthenticateBlocks(input, len);43input += (len - leftOver);44len = leftOver;45}4647if (data && len)48std::memcpy(data, input, len);49num = (unsigned int)len;50}5152void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)53{54m_bufferedDataLength = 0;55m_state = State_Start;5657this->SetKeyWithoutResync(userKey, keylength, params);58m_state = State_KeySet;5960size_t length;61const byte *iv = GetIVAndThrowIfInvalid(params, length);62if (iv)63Resynchronize(iv, (int)length);64}6566void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)67{68if (m_state < State_KeySet)69throw BadState(AlgorithmName(), "Resynchronize", "key is set");7071m_bufferedDataLength = 0;72m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;73m_state = State_KeySet;7475Resync(iv, this->ThrowIfInvalidIVLength(length));76m_state = State_IVSet;77}7879void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length)80{81// Part of original authenc.cpp code. Don't remove it.82if (length == 0) {return;}8384switch (m_state)85{86case State_Start:87case State_KeySet:88throw BadState(AlgorithmName(), "Update", "setting key and IV");89case State_IVSet:90AuthenticateData(input, length);91m_totalHeaderLength += length;92break;93case State_AuthUntransformed:94case State_AuthTransformed:95AuthenticateLastConfidentialBlock();96m_bufferedDataLength = 0;97m_state = State_AuthFooter;98// fall through99case State_AuthFooter:100AuthenticateData(input, length);101m_totalFooterLength += length;102break;103default:104CRYPTOPP_ASSERT(false);105}106}107108void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)109{110if (m_state >= State_IVSet && length > MaxMessageLength()-m_totalMessageLength)111throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");112m_totalMessageLength += length;113114reswitch:115switch (m_state)116{117case State_Start:118case State_KeySet:119throw BadState(AlgorithmName(), "ProcessData", "setting key and IV");120case State_AuthFooter:121throw BadState(AlgorithmName(), "ProcessData was called after footer input has started");122case State_IVSet:123AuthenticateLastHeaderBlock();124m_bufferedDataLength = 0;125m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;126goto reswitch;127case State_AuthUntransformed:128AuthenticateData(inString, length);129AccessSymmetricCipher().ProcessData(outString, inString, length);130break;131case State_AuthTransformed:132AccessSymmetricCipher().ProcessData(outString, inString, length);133AuthenticateData(outString, length);134break;135default:136CRYPTOPP_ASSERT(false);137}138}139140void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize)141{142// https://github.com/weidai11/cryptopp/issues/954143this->ThrowIfInvalidTruncatedSize(macSize);144145if (m_totalHeaderLength > MaxHeaderLength())146throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));147148if (m_totalFooterLength > MaxFooterLength())149{150if (MaxFooterLength() == 0)151throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");152else153throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));154}155156switch (m_state)157{158case State_Start:159case State_KeySet:160throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");161162case State_IVSet:163AuthenticateLastHeaderBlock();164m_bufferedDataLength = 0;165// fall through166167case State_AuthUntransformed:168case State_AuthTransformed:169AuthenticateLastConfidentialBlock();170m_bufferedDataLength = 0;171// fall through172173case State_AuthFooter:174AuthenticateLastFooterBlock(mac, macSize);175m_bufferedDataLength = 0;176break;177178default:179CRYPTOPP_ASSERT(false);180}181182m_state = State_KeySet;183}184185NAMESPACE_END186187#endif188189190