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.

252 lines
7.0 KiB

  1. // strciphr.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #ifndef CRYPTOPP_IMPORTS
  4. #include "strciphr.h"
  5. NAMESPACE_BEGIN(CryptoPP)
  6. template <class S>
  7. void AdditiveCipherTemplate<S>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
  8. {
  9. PolicyInterface &policy = this->AccessPolicy();
  10. policy.CipherSetKey(params, key, length);
  11. m_leftOver = 0;
  12. unsigned int bufferByteSize = policy.CanOperateKeystream() ? GetBufferByteSize(policy) : RoundUpToMultipleOf(1024U, GetBufferByteSize(policy));
  13. m_buffer.New(bufferByteSize);
  14. if (this->IsResynchronizable())
  15. {
  16. size_t ivLength;
  17. const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
  18. policy.CipherResynchronize(m_buffer, iv, ivLength);
  19. }
  20. }
  21. template <class S>
  22. void AdditiveCipherTemplate<S>::GenerateBlock(byte *outString, size_t length)
  23. {
  24. if (m_leftOver > 0)
  25. {
  26. size_t len = STDMIN(m_leftOver, length);
  27. memcpy(outString, KeystreamBufferEnd()-m_leftOver, len);
  28. length -= len;
  29. m_leftOver -= len;
  30. outString += len;
  31. if (!length)
  32. return;
  33. }
  34. assert(m_leftOver == 0);
  35. PolicyInterface &policy = this->AccessPolicy();
  36. unsigned int bytesPerIteration = policy.GetBytesPerIteration();
  37. if (length >= bytesPerIteration)
  38. {
  39. size_t iterations = length / bytesPerIteration;
  40. policy.WriteKeystream(outString, iterations);
  41. outString += iterations * bytesPerIteration;
  42. length -= iterations * bytesPerIteration;
  43. }
  44. if (length > 0)
  45. {
  46. size_t bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
  47. size_t bufferIterations = bufferByteSize / bytesPerIteration;
  48. policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
  49. memcpy(outString, KeystreamBufferEnd()-bufferByteSize, length);
  50. m_leftOver = bufferByteSize - length;
  51. }
  52. }
  53. template <class S>
  54. void AdditiveCipherTemplate<S>::ProcessData(byte *outString, const byte *inString, size_t length)
  55. {
  56. if (m_leftOver > 0)
  57. {
  58. size_t len = STDMIN(m_leftOver, length);
  59. xorbuf(outString, inString, KeystreamBufferEnd()-m_leftOver, len);
  60. length -= len;
  61. m_leftOver -= len;
  62. inString += len;
  63. outString += len;
  64. if (!length)
  65. return;
  66. }
  67. assert(m_leftOver == 0);
  68. PolicyInterface &policy = this->AccessPolicy();
  69. unsigned int bytesPerIteration = policy.GetBytesPerIteration();
  70. if (policy.CanOperateKeystream() && length >= bytesPerIteration)
  71. {
  72. size_t iterations = length / bytesPerIteration;
  73. unsigned int alignment = policy.GetAlignment();
  74. KeystreamOperation operation = KeystreamOperation((IsAlignedOn(inString, alignment) * 2) | (int)IsAlignedOn(outString, alignment));
  75. policy.OperateKeystream(operation, outString, inString, iterations);
  76. inString += iterations * bytesPerIteration;
  77. outString += iterations * bytesPerIteration;
  78. length -= iterations * bytesPerIteration;
  79. if (!length)
  80. return;
  81. }
  82. size_t bufferByteSize = m_buffer.size();
  83. size_t bufferIterations = bufferByteSize / bytesPerIteration;
  84. while (length >= bufferByteSize)
  85. {
  86. policy.WriteKeystream(m_buffer, bufferIterations);
  87. xorbuf(outString, inString, KeystreamBufferBegin(), bufferByteSize);
  88. length -= bufferByteSize;
  89. inString += bufferByteSize;
  90. outString += bufferByteSize;
  91. }
  92. if (length > 0)
  93. {
  94. bufferByteSize = RoundUpToMultipleOf(length, bytesPerIteration);
  95. bufferIterations = bufferByteSize / bytesPerIteration;
  96. policy.WriteKeystream(KeystreamBufferEnd()-bufferByteSize, bufferIterations);
  97. xorbuf(outString, inString, KeystreamBufferEnd()-bufferByteSize, length);
  98. m_leftOver = bufferByteSize - length;
  99. }
  100. }
  101. template <class S>
  102. void AdditiveCipherTemplate<S>::Resynchronize(const byte *iv, int length)
  103. {
  104. PolicyInterface &policy = this->AccessPolicy();
  105. m_leftOver = 0;
  106. m_buffer.New(GetBufferByteSize(policy));
  107. policy.CipherResynchronize(m_buffer, iv, this->ThrowIfInvalidIVLength(length));
  108. }
  109. template <class BASE>
  110. void AdditiveCipherTemplate<BASE>::Seek(lword position)
  111. {
  112. PolicyInterface &policy = this->AccessPolicy();
  113. unsigned int bytesPerIteration = policy.GetBytesPerIteration();
  114. policy.SeekToIteration(position / bytesPerIteration);
  115. position %= bytesPerIteration;
  116. if (position > 0)
  117. {
  118. policy.WriteKeystream(KeystreamBufferEnd()-bytesPerIteration, 1);
  119. m_leftOver = bytesPerIteration - (unsigned int)position;
  120. }
  121. else
  122. m_leftOver = 0;
  123. }
  124. template <class BASE>
  125. void CFB_CipherTemplate<BASE>::UncheckedSetKey(const byte *key, unsigned int length, const NameValuePairs &params)
  126. {
  127. PolicyInterface &policy = this->AccessPolicy();
  128. policy.CipherSetKey(params, key, length);
  129. if (this->IsResynchronizable())
  130. {
  131. size_t ivLength;
  132. const byte *iv = this->GetIVAndThrowIfInvalid(params, ivLength);
  133. policy.CipherResynchronize(iv, ivLength);
  134. }
  135. m_leftOver = policy.GetBytesPerIteration();
  136. }
  137. template <class BASE>
  138. void CFB_CipherTemplate<BASE>::Resynchronize(const byte *iv, int length)
  139. {
  140. PolicyInterface &policy = this->AccessPolicy();
  141. policy.CipherResynchronize(iv, this->ThrowIfInvalidIVLength(length));
  142. m_leftOver = policy.GetBytesPerIteration();
  143. }
  144. template <class BASE>
  145. void CFB_CipherTemplate<BASE>::ProcessData(byte *outString, const byte *inString, size_t length)
  146. {
  147. assert(length % this->MandatoryBlockSize() == 0);
  148. PolicyInterface &policy = this->AccessPolicy();
  149. unsigned int bytesPerIteration = policy.GetBytesPerIteration();
  150. unsigned int alignment = policy.GetAlignment();
  151. byte *reg = policy.GetRegisterBegin();
  152. if (m_leftOver)
  153. {
  154. size_t len = STDMIN(m_leftOver, length);
  155. CombineMessageAndShiftRegister(outString, reg + bytesPerIteration - m_leftOver, inString, len);
  156. m_leftOver -= len;
  157. length -= len;
  158. inString += len;
  159. outString += len;
  160. }
  161. if (!length)
  162. return;
  163. assert(m_leftOver == 0);
  164. if (policy.CanIterate() && length >= bytesPerIteration && IsAlignedOn(outString, alignment))
  165. {
  166. if (IsAlignedOn(inString, alignment))
  167. policy.Iterate(outString, inString, GetCipherDir(*this), length / bytesPerIteration);
  168. else
  169. {
  170. memcpy(outString, inString, length);
  171. policy.Iterate(outString, outString, GetCipherDir(*this), length / bytesPerIteration);
  172. }
  173. inString += length - length % bytesPerIteration;
  174. outString += length - length % bytesPerIteration;
  175. length %= bytesPerIteration;
  176. }
  177. while (length >= bytesPerIteration)
  178. {
  179. policy.TransformRegister();
  180. CombineMessageAndShiftRegister(outString, reg, inString, bytesPerIteration);
  181. length -= bytesPerIteration;
  182. inString += bytesPerIteration;
  183. outString += bytesPerIteration;
  184. }
  185. if (length > 0)
  186. {
  187. policy.TransformRegister();
  188. CombineMessageAndShiftRegister(outString, reg, inString, length);
  189. m_leftOver = bytesPerIteration - length;
  190. }
  191. }
  192. template <class BASE>
  193. void CFB_EncryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
  194. {
  195. xorbuf(reg, message, length);
  196. memcpy(output, reg, length);
  197. }
  198. template <class BASE>
  199. void CFB_DecryptionTemplate<BASE>::CombineMessageAndShiftRegister(byte *output, byte *reg, const byte *message, size_t length)
  200. {
  201. for (unsigned int i=0; i<length; i++)
  202. {
  203. byte b = message[i];
  204. output[i] = reg[i] ^ b;
  205. reg[i] = b;
  206. }
  207. }
  208. NAMESPACE_END
  209. #endif