Team Fortress 2 Source Code as on 22/4/2020
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.

273 lines
8.5 KiB

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