Counter Strike : Global Offensive Source Code
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

180 lines
4.6 KiB

  1. // authenc.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #ifndef CRYPTOPP_IMPORTS
  4. #include "authenc.h"
  5. NAMESPACE_BEGIN(CryptoPP)
  6. void AuthenticatedSymmetricCipherBase::AuthenticateData(const byte *input, size_t len)
  7. {
  8. unsigned int blockSize = AuthenticationBlockSize();
  9. unsigned int &num = m_bufferedDataLength;
  10. byte* data = m_buffer.begin();
  11. if (num != 0) // process left over data
  12. {
  13. if (num+len >= blockSize)
  14. {
  15. memcpy(data+num, input, blockSize-num);
  16. AuthenticateBlocks(data, blockSize);
  17. input += (blockSize-num);
  18. len -= (blockSize-num);
  19. num = 0;
  20. // drop through and do the rest
  21. }
  22. else
  23. {
  24. memcpy(data+num, input, len);
  25. num += (unsigned int)len;
  26. return;
  27. }
  28. }
  29. // now process the input data in blocks of blockSize bytes and save the leftovers to m_data
  30. if (len >= blockSize)
  31. {
  32. size_t leftOver = AuthenticateBlocks(input, len);
  33. input += (len - leftOver);
  34. len = leftOver;
  35. }
  36. memcpy(data, input, len);
  37. num = (unsigned int)len;
  38. }
  39. void AuthenticatedSymmetricCipherBase::SetKey(const byte *userKey, size_t keylength, const NameValuePairs &params)
  40. {
  41. m_bufferedDataLength = 0;
  42. m_state = State_Start;
  43. SetKeyWithoutResync(userKey, keylength, params);
  44. m_state = State_KeySet;
  45. size_t length;
  46. const byte *iv = GetIVAndThrowIfInvalid(params, length);
  47. if (iv)
  48. Resynchronize(iv, (int)length);
  49. }
  50. void AuthenticatedSymmetricCipherBase::Resynchronize(const byte *iv, int length)
  51. {
  52. if (m_state < State_KeySet)
  53. throw BadState(AlgorithmName(), "Resynchronize", "key is set");
  54. m_bufferedDataLength = 0;
  55. m_totalHeaderLength = m_totalMessageLength = m_totalFooterLength = 0;
  56. m_state = State_KeySet;
  57. Resync(iv, this->ThrowIfInvalidIVLength(length));
  58. m_state = State_IVSet;
  59. }
  60. void AuthenticatedSymmetricCipherBase::Update(const byte *input, size_t length)
  61. {
  62. if (length == 0)
  63. return;
  64. switch (m_state)
  65. {
  66. case State_Start:
  67. case State_KeySet:
  68. throw BadState(AlgorithmName(), "Update", "setting key and IV");
  69. case State_IVSet:
  70. AuthenticateData(input, length);
  71. m_totalHeaderLength += length;
  72. break;
  73. case State_AuthUntransformed:
  74. case State_AuthTransformed:
  75. AuthenticateLastConfidentialBlock();
  76. m_bufferedDataLength = 0;
  77. m_state = State_AuthFooter;
  78. // fall through
  79. case State_AuthFooter:
  80. AuthenticateData(input, length);
  81. m_totalFooterLength += length;
  82. break;
  83. default:
  84. assert(false);
  85. }
  86. }
  87. void AuthenticatedSymmetricCipherBase::ProcessData(byte *outString, const byte *inString, size_t length)
  88. {
  89. m_totalMessageLength += length;
  90. if (m_state >= State_IVSet && m_totalMessageLength > MaxMessageLength())
  91. throw InvalidArgument(AlgorithmName() + ": message length exceeds maximum");
  92. reswitch:
  93. switch (m_state)
  94. {
  95. case State_Start:
  96. case State_KeySet:
  97. throw BadState(AlgorithmName(), "ProcessData", "setting key and IV");
  98. case State_AuthFooter:
  99. throw BadState(AlgorithmName(), "ProcessData was called after footer input has started");
  100. case State_IVSet:
  101. AuthenticateLastHeaderBlock();
  102. m_bufferedDataLength = 0;
  103. m_state = AuthenticationIsOnPlaintext()==IsForwardTransformation() ? State_AuthUntransformed : State_AuthTransformed;
  104. goto reswitch;
  105. case State_AuthUntransformed:
  106. AuthenticateData(inString, length);
  107. AccessSymmetricCipher().ProcessData(outString, inString, length);
  108. break;
  109. case State_AuthTransformed:
  110. AccessSymmetricCipher().ProcessData(outString, inString, length);
  111. AuthenticateData(outString, length);
  112. break;
  113. default:
  114. assert(false);
  115. }
  116. }
  117. void AuthenticatedSymmetricCipherBase::TruncatedFinal(byte *mac, size_t macSize)
  118. {
  119. if (m_totalHeaderLength > MaxHeaderLength())
  120. throw InvalidArgument(AlgorithmName() + ": header length of " + IntToString(m_totalHeaderLength) + " exceeds the maximum of " + IntToString(MaxHeaderLength()));
  121. if (m_totalFooterLength > MaxFooterLength())
  122. {
  123. if (MaxFooterLength() == 0)
  124. throw InvalidArgument(AlgorithmName() + ": additional authenticated data (AAD) cannot be input after data to be encrypted or decrypted");
  125. else
  126. throw InvalidArgument(AlgorithmName() + ": footer length of " + IntToString(m_totalFooterLength) + " exceeds the maximum of " + IntToString(MaxFooterLength()));
  127. }
  128. switch (m_state)
  129. {
  130. case State_Start:
  131. case State_KeySet:
  132. throw BadState(AlgorithmName(), "TruncatedFinal", "setting key and IV");
  133. case State_IVSet:
  134. AuthenticateLastHeaderBlock();
  135. m_bufferedDataLength = 0;
  136. // fall through
  137. case State_AuthUntransformed:
  138. case State_AuthTransformed:
  139. AuthenticateLastConfidentialBlock();
  140. m_bufferedDataLength = 0;
  141. // fall through
  142. case State_AuthFooter:
  143. AuthenticateLastFooterBlock(mac, macSize);
  144. m_bufferedDataLength = 0;
  145. break;
  146. default:
  147. assert(false);
  148. }
  149. m_state = State_KeySet;
  150. }
  151. NAMESPACE_END
  152. #endif