Crypto++  5.6.3
Free C++ class library of cryptographic schemes
authenc.cpp
1 // authenc.cpp - 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  unsigned int blockSize = AuthenticationBlockSize();
14  unsigned int &num = m_bufferedDataLength;
15  byte* data = m_buffer.begin();
16 
17  if (num != 0) // process left over data
18  {
19  if (num+len >= blockSize)
20  {
21  memcpy(data+num, input, blockSize-num);
22  AuthenticateBlocks(data, blockSize);
23  input += (blockSize-num);
24  len -= (blockSize-num);
25  num = 0;
26  // drop through and do the rest
27  }
28  else
29  {
30  memcpy(data+num, input, len);
31  num += (unsigned int)len;
32  return;
33  }
34  }
35 
36  // now process the input data in blocks of blockSize bytes and save the leftovers to m_data
37  if (len >= blockSize)
38  {
39  size_t leftOver = AuthenticateBlocks(input, len);
40  input += (len - leftOver);
41  len = leftOver;
42  }
43 
44  memcpy(data, input, len);
45  num = (unsigned int)len;
46 }
47 
48 void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs &params)
49 {
50  m_bufferedDataLength = 0;
51  m_state = State_Start;
52 
53  SetKeyWithoutResync(userKey, keylength, params);
54  m_state = State_KeySet;
55 
56  size_t length;
57  const byte *iv = GetIVAndThrowIfInvalid(params, length);
58  if (iv)
59  Resynchronize(iv, (int)length);
60 }
61 
62 void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)
63 {
64  if (m_state < State_KeySet)
65  throw BadState(AlgorithmName(), "Resynchronize", "key is set");
66 
67  m_bufferedDataLength = 0;
68  m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;
69  m_state = State_KeySet;
70 
71  Resync(iv, this->ThrowIfInvalidIVLength(length));
72  m_state = State_IVSet;
73 }
74 
75 void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length)
76 {
77  if (length == 0)
78  return;
79 
80  switch (m_state)
81  {
82  case State_Start:
83  case State_KeySet:
84  throw BadState(AlgorithmName(), "Update", "setting key and IV");
85  case State_IVSet:
86  AuthenticateData(input, length);
87  m_totalHeaderLength += length;
88  break;
89  case State_AuthUntransformed:
90  case State_AuthTransformed:
91  AuthenticateLastConfidentialBlock();
92  m_bufferedDataLength = 0;
93  m_state = State_AuthFooter;
94  // fall through
95  case State_AuthFooter:
96  AuthenticateData(input, length);
97  m_totalFooterLength += length;
98  break;
99  default:
100  assert(false);
101  }
102 }
103 
104 void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)
105 {
106  m_totalMessageLength += length;
107  if (m_state >= State_IVSet && m_totalMessageLength > MaxMessageLength())
108  throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
109 
110 reswitch:
111  switch (m_state)
112  {
113  case State_Start:
114  case State_KeySet:
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");
118  case State_IVSet:
119  AuthenticateLastHeaderBlock();
120  m_bufferedDataLength = 0;
121  m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;
122  goto reswitch;
123  case State_AuthUntransformed:
124  AuthenticateData(inString, length);
125  AccessSymmetricCipher().ProcessData(outString, inString, length);
126  break;
127  case State_AuthTransformed:
128  AccessSymmetricCipher().ProcessData(outString, inString, length);
129  AuthenticateData(outString, length);
130  break;
131  default:
132  assert(false);
133  }
134 }
135 
137 {
138  if (m_totalHeaderLength > MaxHeaderLength())
139  throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
140 
141  if (m_totalFooterLength > MaxFooterLength())
142  {
143  if (MaxFooterLength() == 0)
144  throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");
145  else
146  throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
147  }
148 
149  switch (m_state)
150  {
151  case State_Start:
152  case State_KeySet:
153  throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");
154 
155  case State_IVSet:
156  AuthenticateLastHeaderBlock();
157  m_bufferedDataLength = 0;
158  // fall through
159 
160  case State_AuthUntransformed:
161  case State_AuthTransformed:
162  AuthenticateLastConfidentialBlock();
163  m_bufferedDataLength = 0;
164  // fall through
165 
166  case State_AuthFooter:
167  AuthenticateLastFooterBlock(mac, macSize);
168  m_bufferedDataLength = 0;
169  break;
170 
171  default:
172  assert(false);
173  }
174 
175  m_state = State_KeySet;
176 }
177 
178 NAMESPACE_END
179 
180 #endif
An invalid argument was detected.
Definition: cryptlib.h:166
virtual void ProcessData(byte *outString, const byte *inString, size_t length)=0
Encrypt or decrypt an array of bytes.
void ProcessData(byte *outString, const byte *inString, size_t length)
Encrypt or decrypt an array of bytes.
Definition: authenc.cpp:104
this indicates that a member function was called in the wrong state, for example trying to encrypt a ...
Definition: cryptlib.h:1040
void Resynchronize(const byte *iv, int length=-1)
resynchronize with an IV. ivLength=-1 means use IVSize()
Definition: authenc.cpp:62
virtual lword MaxMessageLength() const =0
the maximum length of encrypted data
virtual lword MaxFooterLength() const
the maximum length of AAD that can be input after the encrypted data
Definition: cryptlib.h:1052
virtual bool IsForwardTransformation() const =0
Determines if the cipher is being operated in its forward direction.
void SetKey(const byte *userKey, size_t keylength, const NameValuePairs &params)
Sets or reset the key of this object.
Definition: authenc.cpp:48
virtual std::string AlgorithmName() const =0
Provides the name of this algorithm.
void Update(const byte *input, size_t length)
Updates a hash with additional input.
Definition: authenc.cpp:75
std::string IntToString(T value, unsigned int base=10)
Converts a value to a string.
Definition: misc.h:449
Crypto++ library namespace.
void TruncatedFinal(byte *mac, size_t macSize)
Computes the hash of the current message.
Definition: authenc.cpp:136
virtual lword MaxHeaderLength() const =0
the maximum length of AAD that can be input before the encrypted data
Base classes for working with authenticated encryption modes of encryption.
Interface for retrieving values given their names.
Definition: cryptlib.h:261