Coverage Report

Created: 2024-11-21 07:03

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