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.

258 lines
8.1 KiB

  1. // default.cpp - written and placed in the public domain by Wei Dai
  2. #include "pch.h"
  3. #include "default.h"
  4. #include "queue.h"
  5. #include <time.h>
  6. #include <memory>
  7. NAMESPACE_BEGIN(CryptoPP)
  8. static const unsigned int MASH_ITERATIONS = 200;
  9. static const unsigned int SALTLENGTH = 8;
  10. static const unsigned int BLOCKSIZE = Default_BlockCipher::Encryption::BLOCKSIZE;
  11. static const unsigned int KEYLENGTH = Default_BlockCipher::Encryption::DEFAULT_KEYLENGTH;
  12. // The purpose of this function Mash() is to take an arbitrary length input
  13. // string and *deterministicly* produce an arbitrary length output string such
  14. // that (1) it looks random, (2) no information about the input is
  15. // deducible from it, and (3) it contains as much entropy as it can hold, or
  16. // the amount of entropy in the input string, whichever is smaller.
  17. static void Mash(const byte *in, size_t inLen, byte *out, size_t outLen, int iterations)
  18. {
  19. if (BytePrecision(outLen) > 2)
  20. throw InvalidArgument("Mash: output legnth too large");
  21. size_t bufSize = RoundUpToMultipleOf(outLen, (size_t)DefaultHashModule::DIGESTSIZE);
  22. byte b[2];
  23. SecByteBlock buf(bufSize);
  24. SecByteBlock outBuf(bufSize);
  25. DefaultHashModule hash;
  26. unsigned int i;
  27. for(i=0; i<outLen; i+=DefaultHashModule::DIGESTSIZE)
  28. {
  29. b[0] = (byte) (i >> 8);
  30. b[1] = (byte) i;
  31. hash.Update(b, 2);
  32. hash.Update(in, inLen);
  33. hash.Final(outBuf+i);
  34. }
  35. while (iterations-- > 1)
  36. {
  37. memcpy(buf, outBuf, bufSize);
  38. for (i=0; i<bufSize; i+=DefaultHashModule::DIGESTSIZE)
  39. {
  40. b[0] = (byte) (i >> 8);
  41. b[1] = (byte) i;
  42. hash.Update(b, 2);
  43. hash.Update(buf, bufSize);
  44. hash.Final(outBuf+i);
  45. }
  46. }
  47. memcpy(out, outBuf, outLen);
  48. }
  49. static void GenerateKeyIV(const byte *passphrase, size_t passphraseLength, const byte *salt, size_t saltLength, byte *key, byte *IV)
  50. {
  51. SecByteBlock temp(passphraseLength+saltLength);
  52. memcpy(temp, passphrase, passphraseLength);
  53. memcpy(temp+passphraseLength, salt, saltLength);
  54. SecByteBlock keyIV(KEYLENGTH+BLOCKSIZE);
  55. Mash(temp, passphraseLength + saltLength, keyIV, KEYLENGTH+BLOCKSIZE, MASH_ITERATIONS);
  56. memcpy(key, keyIV, KEYLENGTH);
  57. memcpy(IV, keyIV+KEYLENGTH, BLOCKSIZE);
  58. }
  59. // ********************************************************
  60. DefaultEncryptor::DefaultEncryptor(const char *passphrase, BufferedTransformation *attachment)
  61. : ProxyFilter(NULL, 0, 0, attachment), m_passphrase((const byte *)passphrase, strlen(passphrase))
  62. {
  63. }
  64. DefaultEncryptor::DefaultEncryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
  65. : ProxyFilter(NULL, 0, 0, attachment), m_passphrase(passphrase, passphraseLength)
  66. {
  67. }
  68. void DefaultEncryptor::FirstPut(const byte *)
  69. {
  70. // VC60 workaround: __LINE__ expansion bug
  71. CRYPTOPP_COMPILE_ASSERT_INSTANCE(SALTLENGTH <= DefaultHashModule::DIGESTSIZE, 1);
  72. CRYPTOPP_COMPILE_ASSERT_INSTANCE(BLOCKSIZE <= DefaultHashModule::DIGESTSIZE, 2);
  73. SecByteBlock salt(DefaultHashModule::DIGESTSIZE), keyCheck(DefaultHashModule::DIGESTSIZE);
  74. DefaultHashModule hash;
  75. // use hash(passphrase | time | clock) as salt
  76. hash.Update(m_passphrase, m_passphrase.size());
  77. time_t t=time(0);
  78. hash.Update((byte *)&t, sizeof(t));
  79. clock_t c=clock();
  80. hash.Update((byte *)&c, sizeof(c));
  81. hash.Final(salt);
  82. // use hash(passphrase | salt) as key check
  83. hash.Update(m_passphrase, m_passphrase.size());
  84. hash.Update(salt, SALTLENGTH);
  85. hash.Final(keyCheck);
  86. AttachedTransformation()->Put(salt, SALTLENGTH);
  87. // mash passphrase and salt together into key and IV
  88. SecByteBlock key(KEYLENGTH);
  89. SecByteBlock IV(BLOCKSIZE);
  90. GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV);
  91. m_cipher.SetKeyWithIV(key, key.size(), IV);
  92. SetFilter(new StreamTransformationFilter(m_cipher));
  93. m_filter->Put(keyCheck, BLOCKSIZE);
  94. }
  95. void DefaultEncryptor::LastPut(const byte *inString, size_t length)
  96. {
  97. m_filter->MessageEnd();
  98. }
  99. // ********************************************************
  100. DefaultDecryptor::DefaultDecryptor(const char *p, BufferedTransformation *attachment, bool throwException)
  101. : ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
  102. , m_state(WAITING_FOR_KEYCHECK)
  103. , m_passphrase((const byte *)p, strlen(p))
  104. , m_throwException(throwException)
  105. {
  106. }
  107. DefaultDecryptor::DefaultDecryptor(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
  108. : ProxyFilter(NULL, SALTLENGTH+BLOCKSIZE, 0, attachment)
  109. , m_state(WAITING_FOR_KEYCHECK)
  110. , m_passphrase(passphrase, passphraseLength)
  111. , m_throwException(throwException)
  112. {
  113. }
  114. void DefaultDecryptor::FirstPut(const byte *inString)
  115. {
  116. CheckKey(inString, inString+SALTLENGTH);
  117. }
  118. void DefaultDecryptor::LastPut(const byte *inString, size_t length)
  119. {
  120. if (m_filter.get() == NULL)
  121. {
  122. m_state = KEY_BAD;
  123. if (m_throwException)
  124. throw KeyBadErr();
  125. }
  126. else
  127. {
  128. m_filter->MessageEnd();
  129. m_state = WAITING_FOR_KEYCHECK;
  130. }
  131. }
  132. void DefaultDecryptor::CheckKey(const byte *salt, const byte *keyCheck)
  133. {
  134. SecByteBlock check(STDMAX((unsigned int)2*BLOCKSIZE, (unsigned int)DefaultHashModule::DIGESTSIZE));
  135. DefaultHashModule hash;
  136. hash.Update(m_passphrase, m_passphrase.size());
  137. hash.Update(salt, SALTLENGTH);
  138. hash.Final(check);
  139. SecByteBlock key(KEYLENGTH);
  140. SecByteBlock IV(BLOCKSIZE);
  141. GenerateKeyIV(m_passphrase, m_passphrase.size(), salt, SALTLENGTH, key, IV);
  142. m_cipher.SetKeyWithIV(key, key.size(), IV);
  143. std::auto_ptr<StreamTransformationFilter> decryptor(new StreamTransformationFilter(m_cipher));
  144. decryptor->Put(keyCheck, BLOCKSIZE);
  145. decryptor->ForceNextPut();
  146. decryptor->Get(check+BLOCKSIZE, BLOCKSIZE);
  147. SetFilter(decryptor.release());
  148. if (!VerifyBufsEqual(check, check+BLOCKSIZE, BLOCKSIZE))
  149. {
  150. m_state = KEY_BAD;
  151. if (m_throwException)
  152. throw KeyBadErr();
  153. }
  154. else
  155. m_state = KEY_GOOD;
  156. }
  157. // ********************************************************
  158. static DefaultMAC * NewDefaultEncryptorMAC(const byte *passphrase, size_t passphraseLength)
  159. {
  160. size_t macKeyLength = DefaultMAC::StaticGetValidKeyLength(16);
  161. SecByteBlock macKey(macKeyLength);
  162. // since the MAC is encrypted there is no reason to mash the passphrase for many iterations
  163. Mash(passphrase, passphraseLength, macKey, macKeyLength, 1);
  164. return new DefaultMAC(macKey, macKeyLength);
  165. }
  166. DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const char *passphrase, BufferedTransformation *attachment)
  167. : ProxyFilter(NULL, 0, 0, attachment)
  168. , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
  169. {
  170. SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase), true));
  171. }
  172. DefaultEncryptorWithMAC::DefaultEncryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment)
  173. : ProxyFilter(NULL, 0, 0, attachment)
  174. , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
  175. {
  176. SetFilter(new HashFilter(*m_mac, new DefaultEncryptor(passphrase, passphraseLength), true));
  177. }
  178. void DefaultEncryptorWithMAC::LastPut(const byte *inString, size_t length)
  179. {
  180. m_filter->MessageEnd();
  181. }
  182. // ********************************************************
  183. DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const char *passphrase, BufferedTransformation *attachment, bool throwException)
  184. : ProxyFilter(NULL, 0, 0, attachment)
  185. , m_mac(NewDefaultEncryptorMAC((const byte *)passphrase, strlen(passphrase)))
  186. , m_throwException(throwException)
  187. {
  188. SetFilter(new DefaultDecryptor(passphrase, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
  189. }
  190. DefaultDecryptorWithMAC::DefaultDecryptorWithMAC(const byte *passphrase, size_t passphraseLength, BufferedTransformation *attachment, bool throwException)
  191. : ProxyFilter(NULL, 0, 0, attachment)
  192. , m_mac(NewDefaultEncryptorMAC(passphrase, passphraseLength))
  193. , m_throwException(throwException)
  194. {
  195. SetFilter(new DefaultDecryptor(passphrase, passphraseLength, m_hashVerifier=new HashVerifier(*m_mac, NULL, HashVerifier::PUT_MESSAGE), throwException));
  196. }
  197. DefaultDecryptor::State DefaultDecryptorWithMAC::CurrentState() const
  198. {
  199. return static_cast<const DefaultDecryptor *>(m_filter.get())->CurrentState();
  200. }
  201. bool DefaultDecryptorWithMAC::CheckLastMAC() const
  202. {
  203. return m_hashVerifier->GetLastResult();
  204. }
  205. void DefaultDecryptorWithMAC::LastPut(const byte *inString, size_t length)
  206. {
  207. m_filter->MessageEnd();
  208. if (m_throwException && !CheckLastMAC())
  209. throw MACBadErr();
  210. }
  211. NAMESPACE_END