• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

authenc.cpp

00001 // authenc.cpp - written and placed in the public domain by Wei Dai
00002 
00003 #include "pch.h"
00004 
00005 #ifndef CRYPTOPP_IMPORTS
00006 
00007 #include "authenc.h"
00008 
00009 NAMESPACE_BEGIN(CryptoPP)
00010 
00011 void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_t len)
00012 {
00013         unsigned int blockSize = AuthenticationBlockSize();
00014         unsigned int &num = m_bufferedDataLength;
00015         byte* data = m_buffer.begin();
00016 
00017         if (num != 0)   // process left over data
00018         {
00019                 if (num+len >= blockSize)
00020                 {
00021                         memcpy(data+num, input, blockSize-num);
00022                         AuthenticateBlocks(data, blockSize);
00023                         input += (blockSize-num);
00024                         len -= (blockSize-num);
00025                         num = 0;
00026                         // drop through and do the rest
00027                 }
00028                 else
00029                 {
00030                         memcpy(data+num, input, len);
00031                         num += (unsigned int)len;
00032                         return;
00033                 }
00034         }
00035 
00036         // now process the input data in blocks of blockSize bytes and save the leftovers to m_data
00037         if (len >= blockSize)
00038         {
00039                 size_t leftOver = AuthenticateBlocks(input, len);
00040                 input += (len - leftOver);
00041                 len = leftOver;
00042         }
00043 
00044         memcpy(data, input, len);
00045         num = (unsigned int)len;
00046 }
00047 
00048 void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs &params)
00049 {
00050         m_bufferedDataLength = 0;
00051         m_state = State_Start;
00052 
00053         SetKeyWithoutResync(userKey, keylength, params);
00054         m_state = State_KeySet;
00055 
00056         size_t length;
00057         const byte *iv = GetIVAndThrowIfInvalid(params, length);
00058         if (iv)
00059                 Resynchronize(iv, (int)length);
00060 }
00061 
00062 void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)
00063 {
00064         if (m_state < State_KeySet)
00065                 throw BadState(AlgorithmName(), "Resynchronize", "key is set");
00066 
00067         m_bufferedDataLength = 0;
00068         m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;
00069         m_state = State_KeySet;
00070 
00071         Resync(iv, this->ThrowIfInvalidIVLength(length));
00072         m_state = State_IVSet;
00073 }
00074 
00075 void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length)
00076 {
00077         if (length == 0)
00078                 return;
00079 
00080         switch (m_state)
00081         {
00082         case State_Start:
00083         case State_KeySet:
00084                 throw BadState(AlgorithmName(), "Update", "setting key and IV");
00085         case State_IVSet:
00086                 AuthenticateData(input, length);
00087                 m_totalHeaderLength += length;
00088                 break;
00089         case State_AuthUntransformed:
00090         case State_AuthTransformed:
00091                 AuthenticateLastConfidentialBlock();
00092                 m_bufferedDataLength = 0;
00093                 m_state = State_AuthFooter;
00094                 // fall through
00095         case State_AuthFooter:
00096                 AuthenticateData(input, length);
00097                 m_totalFooterLength += length;
00098                 break;
00099         default:
00100                 assert(false);
00101         }
00102 }
00103 
00104 void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)
00105 {
00106         m_totalMessageLength += length;
00107         if (m_state >= State_IVSet && m_totalMessageLength > MaxMessageLength())
00108                 throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
00109 
00110 reswitch:
00111         switch (m_state)
00112         {
00113         case State_Start:
00114         case State_KeySet:
00115                 throw BadState(AlgorithmName(), "ProcessData", "setting key and IV");
00116         case State_AuthFooter:
00117                 throw BadState(AlgorithmName(), "ProcessData was called after footer input has started");
00118         case State_IVSet:
00119                 AuthenticateLastHeaderBlock();
00120                 m_bufferedDataLength = 0;
00121                 m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;
00122                 goto reswitch;
00123         case State_AuthUntransformed:
00124                 AuthenticateData(inString, length);
00125                 AccessSymmetricCipher().ProcessData(outString, inString, length);
00126                 break;
00127         case State_AuthTransformed:
00128                 AccessSymmetricCipher().ProcessData(outString, inString, length);
00129                 AuthenticateData(outString, length);
00130                 break;
00131         default:
00132                 assert(false);
00133         }
00134 }
00135 
00136 void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize)
00137 {
00138         if (m_totalHeaderLength > MaxHeaderLength())
00139                 throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
00140 
00141         if (m_totalFooterLength > MaxFooterLength())
00142         {
00143                 if (MaxFooterLength() == 0)
00144                         throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");
00145                 else
00146                         throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
00147         }
00148 
00149         switch (m_state)
00150         {
00151         case State_Start:
00152         case State_KeySet:
00153                 throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");
00154 
00155         case State_IVSet:
00156                 AuthenticateLastHeaderBlock();
00157                 m_bufferedDataLength = 0;
00158                 // fall through
00159 
00160         case State_AuthUntransformed:
00161         case State_AuthTransformed:
00162                 AuthenticateLastConfidentialBlock();
00163                 m_bufferedDataLength = 0;
00164                 // fall through
00165 
00166         case State_AuthFooter:
00167                 AuthenticateLastFooterBlock(mac, macSize);
00168                 m_bufferedDataLength = 0;
00169                 break;
00170 
00171         default:
00172                 assert(false);
00173         }
00174 
00175         m_state = State_KeySet;
00176 }
00177 
00178 NAMESPACE_END
00179 
00180 #endif

Generated on Mon Aug 9 2010 15:56:32 for Crypto++ by  doxygen 1.7.1