1
// authenc.cpp - written and placed in the public domain by Wei Dai
5
#ifndef CRYPTOPP_IMPORTS
9
NAMESPACE_BEGIN(CryptoPP)
11
void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_t len)
13
unsigned int blockSize = AuthenticationBlockSize();
14
unsigned int &num = m_bufferedDataLength;
15
byte* data = m_buffer.begin();
17
if (num != 0) // process left over data
19
if (num+len >= blockSize)
21
memcpy(data+num, input, blockSize-num);
22
AuthenticateBlocks(data, blockSize);
23
input += (blockSize-num);
24
len -= (blockSize-num);
26
// drop through and do the rest
30
memcpy(data+num, input, len);
31
num += (unsigned int)len;
36
// now process the input data in blocks of blockSize bytes and save the leftovers to m_data
39
size_t leftOver = AuthenticateBlocks(input, len);
40
input += (len - leftOver);
44
memcpy(data, input, len);
45
num = (unsigned int)len;
48
void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs ¶ms)
50
m_bufferedDataLength = 0;
51
m_state = State_Start;
53
SetKeyWithoutResync(userKey, keylength, params);
54
m_state = State_KeySet;
57
const byte *iv = GetIVAndThrowIfInvalid(params, length);
59
Resynchronize(iv, (int)length);
62
void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)
64
if (m_state < State_KeySet)
65
throw BadState(AlgorithmName(), "Resynchronize", "key is set");
67
m_bufferedDataLength = 0;
68
m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;
69
m_state = State_KeySet;
71
Resync(iv, this->ThrowIfInvalidIVLength(length));
72
m_state = State_IVSet;
75
void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length)
84
throw BadState(AlgorithmName(), "Update", "setting key and IV");
86
AuthenticateData(input, length);
87
m_totalHeaderLength += length;
89
case State_AuthUntransformed:
90
case State_AuthTransformed:
91
AuthenticateLastConfidentialBlock();
92
m_bufferedDataLength = 0;
93
m_state = State_AuthFooter;
95
case State_AuthFooter:
96
AuthenticateData(input, length);
97
m_totalFooterLength += length;
104
void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)
106
m_totalMessageLength += length;
107
if (m_state >= State_IVSet && m_totalMessageLength > MaxMessageLength())
108
throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
115
throw BadState(AlgorithmName(), "ProcessData", "setting key and IV");
116
case State_AuthFooter:
117
throw BadState(AlgorithmName(), "ProcessData was called after footer input has started");
119
AuthenticateLastHeaderBlock();
120
m_bufferedDataLength = 0;
121
m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;
123
case State_AuthUntransformed:
124
AuthenticateData(inString, length);
125
AccessSymmetricCipher().ProcessData(outString, inString, length);
127
case State_AuthTransformed:
128
AccessSymmetricCipher().ProcessData(outString, inString, length);
129
AuthenticateData(outString, length);
136
void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize)
138
if (m_totalHeaderLength > MaxHeaderLength())
139
throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
141
if (m_totalFooterLength > MaxFooterLength())
143
if (MaxFooterLength() == 0)
144
throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");
146
throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
153
throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");
156
AuthenticateLastHeaderBlock();
157
m_bufferedDataLength = 0;
160
case State_AuthUntransformed:
161
case State_AuthTransformed:
162
AuthenticateLastConfidentialBlock();
163
m_bufferedDataLength = 0;
166
case State_AuthFooter:
167
AuthenticateLastFooterBlock(mac, macSize);
168
m_bufferedDataLength = 0;
175
m_state = State_KeySet;