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.

245 lines
7.3 KiB

  1. // modes.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #ifndef CRYPTOPP_IMPORTS
  4. #include "modes.h"
  5. #ifndef NDEBUG
  6. #include "des.h"
  7. #endif
  8. NAMESPACE_BEGIN(CryptoPP)
  9. #ifndef NDEBUG
  10. void Modes_TestInstantiations()
  11. {
  12. CFB_Mode<DES>::Encryption m0;
  13. CFB_Mode<DES>::Decryption m1;
  14. OFB_Mode<DES>::Encryption m2;
  15. CTR_Mode<DES>::Encryption m3;
  16. ECB_Mode<DES>::Encryption m4;
  17. CBC_Mode<DES>::Encryption m5;
  18. }
  19. #endif
  20. void CFB_ModePolicy::Iterate(byte *output, const byte *input, CipherDir dir, size_t iterationCount)
  21. {
  22. assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
  23. assert(m_feedbackSize == BlockSize());
  24. unsigned int s = BlockSize();
  25. if (dir == ENCRYPTION)
  26. {
  27. m_cipher->ProcessAndXorBlock(m_register, input, output);
  28. m_cipher->AdvancedProcessBlocks(output, input+s, output+s, (iterationCount-1)*s, 0);
  29. memcpy(m_register, output+(iterationCount-1)*s, s);
  30. }
  31. else
  32. {
  33. memcpy(m_temp, input+(iterationCount-1)*s, s); // make copy first in case of in-place decryption
  34. m_cipher->AdvancedProcessBlocks(input, input+s, output+s, (iterationCount-1)*s, BlockTransformation::BT_ReverseDirection);
  35. m_cipher->ProcessAndXorBlock(m_register, input, output);
  36. memcpy(m_register, m_temp, s);
  37. }
  38. }
  39. void CFB_ModePolicy::TransformRegister()
  40. {
  41. assert(m_cipher->IsForwardTransformation()); // CFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
  42. m_cipher->ProcessBlock(m_register, m_temp);
  43. unsigned int updateSize = BlockSize()-m_feedbackSize;
  44. memmove_s(m_register, m_register.size(), m_register+m_feedbackSize, updateSize);
  45. memcpy_s(m_register+updateSize, m_register.size()-updateSize, m_temp, m_feedbackSize);
  46. }
  47. void CFB_ModePolicy::CipherResynchronize(const byte *iv, size_t length)
  48. {
  49. assert(length == BlockSize());
  50. CopyOrZero(m_register, iv, length);
  51. TransformRegister();
  52. }
  53. void CFB_ModePolicy::SetFeedbackSize(unsigned int feedbackSize)
  54. {
  55. if (feedbackSize > BlockSize())
  56. throw InvalidArgument("CFB_Mode: invalid feedback size");
  57. m_feedbackSize = feedbackSize ? feedbackSize : BlockSize();
  58. }
  59. void CFB_ModePolicy::ResizeBuffers()
  60. {
  61. CipherModeBase::ResizeBuffers();
  62. m_temp.New(BlockSize());
  63. }
  64. void OFB_ModePolicy::WriteKeystream(byte *keystreamBuffer, size_t iterationCount)
  65. {
  66. assert(m_cipher->IsForwardTransformation()); // OFB mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
  67. unsigned int s = BlockSize();
  68. m_cipher->ProcessBlock(m_register, keystreamBuffer);
  69. if (iterationCount > 1)
  70. m_cipher->AdvancedProcessBlocks(keystreamBuffer, NULL, keystreamBuffer+s, s*(iterationCount-1), 0);
  71. memcpy(m_register, keystreamBuffer+s*(iterationCount-1), s);
  72. }
  73. void OFB_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
  74. {
  75. assert(length == BlockSize());
  76. CopyOrZero(m_register, iv, length);
  77. }
  78. void CTR_ModePolicy::SeekToIteration(lword iterationCount)
  79. {
  80. int carry=0;
  81. for (int i=BlockSize()-1; i>=0; i--)
  82. {
  83. unsigned int sum = m_register[i] + byte(iterationCount) + carry;
  84. m_counterArray[i] = (byte) sum;
  85. carry = sum >> 8;
  86. iterationCount >>= 8;
  87. }
  88. }
  89. void CTR_ModePolicy::IncrementCounterBy256()
  90. {
  91. IncrementCounterByOne(m_counterArray, BlockSize()-1);
  92. }
  93. void CTR_ModePolicy::OperateKeystream(KeystreamOperation operation, byte *output, const byte *input, size_t iterationCount)
  94. {
  95. assert(m_cipher->IsForwardTransformation()); // CTR mode needs the "encrypt" direction of the underlying block cipher, even to decrypt
  96. unsigned int s = BlockSize();
  97. unsigned int inputIncrement = input ? s : 0;
  98. while (iterationCount)
  99. {
  100. byte lsb = m_counterArray[s-1];
  101. size_t blocks = UnsignedMin(iterationCount, 256U-lsb);
  102. m_cipher->AdvancedProcessBlocks(m_counterArray, input, output, blocks*s, BlockTransformation::BT_InBlockIsCounter|BlockTransformation::BT_AllowParallel);
  103. if ((m_counterArray[s-1] = lsb + (byte)blocks) == 0)
  104. IncrementCounterBy256();
  105. output += blocks*s;
  106. input += blocks*inputIncrement;
  107. iterationCount -= blocks;
  108. }
  109. }
  110. void CTR_ModePolicy::CipherResynchronize(byte *keystreamBuffer, const byte *iv, size_t length)
  111. {
  112. assert(length == BlockSize());
  113. CopyOrZero(m_register, iv, length);
  114. m_counterArray = m_register;
  115. }
  116. void BlockOrientedCipherModeBase::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
  117. {
  118. m_cipher->SetKey(key, length, params);
  119. ResizeBuffers();
  120. if (IsResynchronizable())
  121. {
  122. size_t ivLength;
  123. const byte *iv = GetIVAndThrowIfInvalid(params, ivLength);
  124. Resynchronize(iv, (int)ivLength);
  125. }
  126. }
  127. void ECB_OneWay::ProcessData(byte *outString, const byte *inString, size_t length)
  128. {
  129. assert(length%BlockSize()==0);
  130. m_cipher->AdvancedProcessBlocks(inString, NULL, outString, length, BlockTransformation::BT_AllowParallel);
  131. }
  132. void CBC_Encryption::ProcessData(byte *outString, const byte *inString, size_t length)
  133. {
  134. if (!length)
  135. return;
  136. assert(length%BlockSize()==0);
  137. unsigned int blockSize = BlockSize();
  138. m_cipher->AdvancedProcessBlocks(inString, m_register, outString, blockSize, BlockTransformation::BT_XorInput);
  139. if (length > blockSize)
  140. m_cipher->AdvancedProcessBlocks(inString+blockSize, outString, outString+blockSize, length-blockSize, BlockTransformation::BT_XorInput);
  141. memcpy(m_register, outString + length - blockSize, blockSize);
  142. }
  143. void CBC_CTS_Encryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
  144. {
  145. if (length <= BlockSize())
  146. {
  147. if (!m_stolenIV)
  148. throw InvalidArgument("CBC_Encryption: message is too short for ciphertext stealing");
  149. // steal from IV
  150. memcpy(outString, m_register, length);
  151. outString = m_stolenIV;
  152. }
  153. else
  154. {
  155. // steal from next to last block
  156. xorbuf(m_register, inString, BlockSize());
  157. m_cipher->ProcessBlock(m_register);
  158. inString += BlockSize();
  159. length -= BlockSize();
  160. memcpy(outString+BlockSize(), m_register, length);
  161. }
  162. // output last full ciphertext block
  163. xorbuf(m_register, inString, length);
  164. m_cipher->ProcessBlock(m_register);
  165. memcpy(outString, m_register, BlockSize());
  166. }
  167. void CBC_Decryption::ProcessData(byte *outString, const byte *inString, size_t length)
  168. {
  169. if (!length)
  170. return;
  171. assert(length%BlockSize()==0);
  172. unsigned int blockSize = BlockSize();
  173. memcpy(m_temp, inString+length-blockSize, blockSize); // save copy now in case of in-place decryption
  174. if (length > blockSize)
  175. m_cipher->AdvancedProcessBlocks(inString+blockSize, inString, outString+blockSize, length-blockSize, BlockTransformation::BT_ReverseDirection|BlockTransformation::BT_AllowParallel);
  176. m_cipher->ProcessAndXorBlock(inString, m_register, outString);
  177. m_register.swap(m_temp);
  178. }
  179. void CBC_CTS_Decryption::ProcessLastBlock(byte *outString, const byte *inString, size_t length)
  180. {
  181. const byte *pn, *pn1;
  182. bool stealIV = length <= BlockSize();
  183. if (stealIV)
  184. {
  185. pn = inString;
  186. pn1 = m_register;
  187. }
  188. else
  189. {
  190. pn = inString + BlockSize();
  191. pn1 = inString;
  192. length -= BlockSize();
  193. }
  194. // decrypt last partial plaintext block
  195. memcpy(m_temp, pn1, BlockSize());
  196. m_cipher->ProcessBlock(m_temp);
  197. xorbuf(m_temp, pn, length);
  198. if (stealIV)
  199. memcpy(outString, m_temp, length);
  200. else
  201. {
  202. memcpy(outString+BlockSize(), m_temp, length);
  203. // decrypt next to last plaintext block
  204. memcpy(m_temp, pn, length);
  205. m_cipher->ProcessBlock(m_temp);
  206. xorbuf(outString, m_temp, m_register, BlockSize());
  207. }
  208. }
  209. NAMESPACE_END
  210. #endif