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:182
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
Exception thrown when the object is in the wrong state for the operation.
Definition: cryptlib.h:1127
void Resynchronize(const byte *iv, int length=-1)
Resynchronize with an IV.
Definition: authenc.cpp:62
virtual lword MaxMessageLength() const =0
Provides the maximum length of encrypted data.
virtual lword MaxFooterLength() const
Provides the the maximum length of AAD.
Definition: cryptlib.h:1142
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
Base implementation for one direction (encryption or decryption) of a stream cipher or block cipher m...
Definition: authenc.h:17
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:494
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
Provides the maximum length of AAD that can be input.
Base classes for working with authenticated encryption modes of encryption.
Interface for retrieving values given their names.
Definition: cryptlib.h:277