Crypto++  7.0
Free C++ class library of cryptographic schemes
authenc.cpp
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  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  this->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) {return;}
78 
79  switch (m_state)
80  {
81  case State_Start:
82  case State_KeySet:
83  throw BadState(AlgorithmName(), "Update", "setting key and IV");
84  case State_IVSet:
85  AuthenticateData(input, length);
86  m_totalHeaderLength += length;
87  break;
88  case State_AuthUntransformed:
89  case State_AuthTransformed:
90  AuthenticateLastConfidentialBlock();
91  m_bufferedDataLength = 0;
92  m_state = State_AuthFooter;
93  // fall through
94  case State_AuthFooter:
95  AuthenticateData(input, length);
96  m_totalFooterLength += length;
97  break;
98  default:
99  CRYPTOPP_ASSERT(false);
100  }
101 }
102 
103 void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)
104 {
105  m_totalMessageLength += length;
106  if (m_state >= State_IVSet && m_totalMessageLength > MaxMessageLength())
107  throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
108 
109 reswitch:
110  switch (m_state)
111  {
112  case State_Start:
113  case State_KeySet:
114  throw BadState(AlgorithmName(), "ProcessData", "setting key and IV");
115  case State_AuthFooter:
116  throw BadState(AlgorithmName(), "ProcessData was called after footer input has started");
117  case State_IVSet:
118  AuthenticateLastHeaderBlock();
119  m_bufferedDataLength = 0;
120  m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;
121  goto reswitch;
122  case State_AuthUntransformed:
123  AuthenticateData(inString, length);
124  AccessSymmetricCipher().ProcessData(outString, inString, length);
125  break;
126  case State_AuthTransformed:
127  AccessSymmetricCipher().ProcessData(outString, inString, length);
128  AuthenticateData(outString, length);
129  break;
130  default:
131  CRYPTOPP_ASSERT(false);
132  }
133 }
134 
136 {
137  if (m_totalHeaderLength > MaxHeaderLength())
138  throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
139 
140  if (m_totalFooterLength > MaxFooterLength())
141  {
142  if (MaxFooterLength() == 0)
143  throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");
144  else
145  throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
146  }
147 
148  switch (m_state)
149  {
150  case State_Start:
151  case State_KeySet:
152  throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");
153 
154  case State_IVSet:
155  AuthenticateLastHeaderBlock();
156  m_bufferedDataLength = 0;
157  // fall through
158 
159  case State_AuthUntransformed:
160  case State_AuthTransformed:
161  AuthenticateLastConfidentialBlock();
162  m_bufferedDataLength = 0;
163  // fall through
164 
165  case State_AuthFooter:
166  AuthenticateLastFooterBlock(mac, macSize);
167  m_bufferedDataLength = 0;
168  break;
169 
170  default:
171  CRYPTOPP_ASSERT(false);
172  }
173 
174  m_state = State_KeySet;
175 }
176 
177 NAMESPACE_END
178 
179 #endif
An invalid argument was detected.
Definition: cryptlib.h:202
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:103
Exception thrown when the object is in the wrong state for the operation.
Definition: cryptlib.h:1294
void Resynchronize(const byte *iv, int length=-1)
Resynchronize with an IV.
Definition: authenc.cpp:62
virtual lword MaxHeaderLength() const =0
Provides the maximum length of AAD that can be input.
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
Precompiled header file.
virtual std::string AlgorithmName() const
Provides the name of this algorithm.
Definition: cryptlib.cpp:265
#define CRYPTOPP_ASSERT(exp)
Debugging and diagnostic assertion.
Definition: trap.h:60
iterator begin()
Provides an iterator pointing to the first element in the memory block.
Definition: secblock.h:766
virtual lword MaxMessageLength() const =0
Provides the maximum length of encrypted data.
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:632
Crypto++ library namespace.
void TruncatedFinal(byte *mac, size_t macSize)
Computes the hash of the current message.
Definition: authenc.cpp:135
virtual lword MaxFooterLength() const
Provides the the maximum length of AAD.
Definition: cryptlib.h:1309
Classes for authenticated encryption modes of operation.
Interface for retrieving values given their names.
Definition: cryptlib.h:293