Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
folium-app
GitHub Repository: folium-app/Folium
Path: blob/a-new-beginning/SharedDependencies/Sources/cryptopp/authenc.cpp
2 views
1
// authenc.cpp - originally written and placed in the public domain by Wei Dai
2
3
#include "pch.h"
4
5
#ifndef CRYPTOPP_IMPORTS
6
7
#include "authenc.h"
8
9
NAMESPACE_BEGIN(CryptoPP)
10
11
void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_t len)
12
{
13
// UBsan finding with -std=c++03 using memcpy
14
CRYPTOPP_ASSERT(input && len);
15
if(!input || !len) return;
16
17
unsigned int blockSize = AuthenticationBlockSize();
18
unsigned int &num = m_bufferedDataLength;
19
byte* data = m_buffer.begin();
20
21
if (data && num) // process left over data
22
{
23
if (num+len >= blockSize)
24
{
25
std::memcpy(data+num, input, blockSize-num);
26
AuthenticateBlocks(data, blockSize);
27
input += (blockSize-num);
28
len -= (blockSize-num);
29
num = 0;
30
// drop through and do the rest
31
}
32
else
33
{
34
std::memcpy(data+num, input, len);
35
num += (unsigned int)len;
36
return;
37
}
38
}
39
40
// now process the input data in blocks of blockSize bytes and save the leftovers to m_data
41
if (len >= blockSize)
42
{
43
size_t leftOver = AuthenticateBlocks(input, len);
44
input += (len - leftOver);
45
len = leftOver;
46
}
47
48
if (data && len)
49
std::memcpy(data, input, len);
50
num = (unsigned int)len;
51
}
52
53
void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs &params)
54
{
55
m_bufferedDataLength = 0;
56
m_state = State_Start;
57
58
this->SetKeyWithoutResync(userKey, keylength, params);
59
m_state = State_KeySet;
60
61
size_t length;
62
const byte *iv = GetIVAndThrowIfInvalid(params, length);
63
if (iv)
64
Resynchronize(iv, (int)length);
65
}
66
67
void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)
68
{
69
if (m_state < State_KeySet)
70
throw BadState(AlgorithmName(), "Resynchronize", "key is set");
71
72
m_bufferedDataLength = 0;
73
m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;
74
m_state = State_KeySet;
75
76
Resync(iv, this->ThrowIfInvalidIVLength(length));
77
m_state = State_IVSet;
78
}
79
80
void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length)
81
{
82
// Part of original authenc.cpp code. Don't remove it.
83
if (length == 0) {return;}
84
85
switch (m_state)
86
{
87
case State_Start:
88
case State_KeySet:
89
throw BadState(AlgorithmName(), "Update", "setting key and IV");
90
case State_IVSet:
91
AuthenticateData(input, length);
92
m_totalHeaderLength += length;
93
break;
94
case State_AuthUntransformed:
95
case State_AuthTransformed:
96
AuthenticateLastConfidentialBlock();
97
m_bufferedDataLength = 0;
98
m_state = State_AuthFooter;
99
// fall through
100
case State_AuthFooter:
101
AuthenticateData(input, length);
102
m_totalFooterLength += length;
103
break;
104
default:
105
CRYPTOPP_ASSERT(false);
106
}
107
}
108
109
void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)
110
{
111
if (m_state >= State_IVSet && length > MaxMessageLength()-m_totalMessageLength)
112
throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
113
m_totalMessageLength += length;
114
115
reswitch:
116
switch (m_state)
117
{
118
case State_Start:
119
case State_KeySet:
120
throw BadState(AlgorithmName(), "ProcessData", "setting key and IV");
121
case State_AuthFooter:
122
throw BadState(AlgorithmName(), "ProcessData was called after footer input has started");
123
case State_IVSet:
124
AuthenticateLastHeaderBlock();
125
m_bufferedDataLength = 0;
126
m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;
127
goto reswitch;
128
case State_AuthUntransformed:
129
AuthenticateData(inString, length);
130
AccessSymmetricCipher().ProcessData(outString, inString, length);
131
break;
132
case State_AuthTransformed:
133
AccessSymmetricCipher().ProcessData(outString, inString, length);
134
AuthenticateData(outString, length);
135
break;
136
default:
137
CRYPTOPP_ASSERT(false);
138
}
139
}
140
141
void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize)
142
{
143
// https://github.com/weidai11/cryptopp/issues/954
144
this->ThrowIfInvalidTruncatedSize(macSize);
145
146
if (m_totalHeaderLength > MaxHeaderLength())
147
throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
148
149
if (m_totalFooterLength > MaxFooterLength())
150
{
151
if (MaxFooterLength() == 0)
152
throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");
153
else
154
throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
155
}
156
157
switch (m_state)
158
{
159
case State_Start:
160
case State_KeySet:
161
throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");
162
163
case State_IVSet:
164
AuthenticateLastHeaderBlock();
165
m_bufferedDataLength = 0;
166
// fall through
167
168
case State_AuthUntransformed:
169
case State_AuthTransformed:
170
AuthenticateLastConfidentialBlock();
171
m_bufferedDataLength = 0;
172
// fall through
173
174
case State_AuthFooter:
175
AuthenticateLastFooterBlock(mac, macSize);
176
m_bufferedDataLength = 0;
177
break;
178
179
default:
180
CRYPTOPP_ASSERT(false);
181
}
182
183
m_state = State_KeySet;
184
}
185
186
NAMESPACE_END
187
188
#endif
189
190