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.

281 lines
14 KiB

  1. //========= Copyright Valve Corporation, All rights reserved. ============//
  2. //
  3. // Purpose: This module is for wrapping Crypto++ functions, including crypto++
  4. // directly has nasty consequences polluting the global namespace, and
  5. // conflicting with xdebug and locale stuff, so we only include it here
  6. // and use this wrapper in the rest of our code.
  7. //
  8. // $NoKeywords: $
  9. //=============================================================================
  10. #ifndef CRYPTO_H
  11. #define CRYPTO_H
  12. #include <tier0/dbg.h> // for Assert & AssertMsg
  13. #include "tier1/passwordhash.h"
  14. #include "tier1/utlmemory.h"
  15. #include <steam/steamtypes.h> // for Salt_t
  16. extern void FreeListRNG();
  17. const unsigned int k_cubSHA256Hash = 32;
  18. typedef unsigned char SHA256Digest_t[ k_cubSHA256Hash ];
  19. const int k_nSymmetricBlockSize = 16; // AES block size (128 bits)
  20. const int k_nSymmetricKeyLen = 32; // length in bytes of keys used for symmetric encryption
  21. const int k_nRSAKeyLenMax = 1024; // max length in bytes of keys used for RSA encryption (includes DER encoding)
  22. const int k_nRSAKeyLenMaxEncoded = k_nRSAKeyLenMax*2; // max length in bytes of hex-encoded key (hex encoding exactly doubles size)
  23. const int k_nRSAKeyBits = 1024; // length in bits of keys used for RSA encryption
  24. const int k_cubRSAEncryptedBlockSize = 128;
  25. const int k_cubRSAPlaintextBlockSize = 86 + 1; // assume plaintext is text, so add a byte for the trailing \0
  26. const uint32 k_cubRSASignature = k_cubRSAEncryptedBlockSize;
  27. // Simple buffer class to encapsulate output from crypto functions with unknown output size
  28. class CCryptoOutBuffer
  29. {
  30. public:
  31. CCryptoOutBuffer()
  32. {
  33. m_pubData = NULL;
  34. m_cubData = 0;
  35. }
  36. ~CCryptoOutBuffer()
  37. {
  38. if ( m_pubData )
  39. delete[] m_pubData;
  40. m_pubData = NULL;
  41. m_cubData = 0;
  42. }
  43. void Set( uint8 *pubData, uint32 cubData )
  44. {
  45. if ( !pubData || !cubData )
  46. return;
  47. if ( m_pubData )
  48. delete[] m_pubData;
  49. m_pubData = new uint8[ cubData ];
  50. memcpy( m_pubData, pubData, cubData );
  51. m_cubData = cubData;
  52. }
  53. void Allocate( uint32 cubData )
  54. {
  55. if ( m_pubData )
  56. delete[] m_pubData;
  57. m_pubData = new uint8[ cubData ];
  58. m_cubData = cubData;
  59. }
  60. void Trim( uint32 cubTrim )
  61. {
  62. Assert( cubTrim <= m_cubData );
  63. m_cubData = cubTrim;
  64. }
  65. uint8 *PubData() { return m_pubData; }
  66. uint32 CubData() { return m_cubData; }
  67. private:
  68. uint8 *m_pubData;
  69. uint32 m_cubData;
  70. };
  71. #if !defined(_PS3)
  72. class CCrypto
  73. {
  74. public:
  75. static uint32 GetSymmetricEncryptedSize( uint32 cubPlaintextData );
  76. // this method writes the encrypted IV, then the ciphertext
  77. static bool SymmetricEncryptWithIV( const uint8 * pubPlaintextData, uint32 cubPlaintextData,
  78. const uint8 * pIV, uint32 cubIV,
  79. uint8 * pubEncryptedData, uint32 * pcubEncryptedData,
  80. const uint8 * pubKey, uint32 cubKey );
  81. static bool SymmetricEncrypt( const uint8 * pubPlaintextData, uint32 cubPlaintextData,
  82. uint8 * pubEncryptedData, uint32 * pcubEncryptedData,
  83. const uint8 * pubKey, uint32 cubKey );
  84. // this method assumes there is no IV before the payload - dissimilar to SymmetricEncryptWithIV
  85. static bool SymmetricDecryptWithIV( const uint8 * pubEncryptedData, uint32 cubEncryptedData,
  86. const uint8 * pIV, uint32 cubIV,
  87. uint8 * pubPlaintextData, uint32 * pcubPlaintextData,
  88. const uint8 * pubKey, uint32 cubKey );
  89. static bool SymmetricDecrypt( const uint8 * pubEncryptedData, uint32 cubEncryptedData,
  90. uint8 * pubPlaintextData, uint32 * pcubPlaintextData,
  91. const uint8 * pubKey, uint32 cubKey );
  92. // symmetrically encrypt data with a text password. A SHA256 hash of the password
  93. // is used as an AES encryption key (calls SymmetricEncrypt, above).
  94. // An HMAC of the ciphertext is appended, for authentication.
  95. static bool EncryptWithPasswordAndHMAC( const uint8 *pubPlaintextData, uint32 cubPlaintextData,
  96. uint8 * pubEncryptedData, uint32 * pcubEncryptedData,
  97. const char *pchPassword );
  98. // Same as above but uses an explicit IV. The format of the ciphertext is the same.
  99. // Be sure you know what you're doing if you use this - a random IV is much more secure in general!
  100. static bool EncryptWithPasswordAndHMACWithIV( const uint8 *pubPlaintextData, uint32 cubPlaintextData,
  101. const uint8 * pIV, uint32 cubIV,
  102. uint8 * pubEncryptedData, uint32 * pcubEncryptedData,
  103. const char *pchPassword );
  104. // Symmetrically decrypt data with the given password (see above).
  105. // If the HMAC does not match what we expect, then we know that either the password is
  106. // incorrect or the message is corrupted.
  107. static bool DecryptWithPasswordAndAuthenticate( const uint8 * pubEncryptedData, uint32 cubEncryptedData,
  108. uint8 * pubPlaintextData, uint32 * pcubPlaintextData,
  109. const char *pchPassword );
  110. static bool RSAGenerateKeys( uint8 *pubPublicKey, uint32 *pcubPublicKey, uint8 *pubPrivateKey, uint32 *pcubPrivateKey );
  111. static bool RSAEncrypt( const uint8 *pubPlaintextPlaintextData, const uint32 cubData, uint8 *pubEncryptedData,
  112. uint32 *pcubEncryptedData, const uint8 *pubPublicKey, const uint32 cubPublicKey );
  113. static bool RSADecrypt( const uint8 *pubEncryptedData, uint32 cubEncryptedData,
  114. uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubPrivateKey, const uint32 cubPrivateKey );
  115. // decrypt using a public key, and no padding
  116. static bool RSAPublicDecrypt_NoPadding( const uint8 *pubEncryptedData, uint32 cubEncryptedData,
  117. uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubPublicKey, const uint32 cubPublicKey );
  118. static bool RSASign( const uint8 *pubData, const uint32 cubData,
  119. uint8 *pubSignature, uint32 *pcubSignature,
  120. const uint8 * pubPrivateKey, const uint32 cubPrivateKey );
  121. static bool RSAVerifySignature( const uint8 *pubData, const uint32 cubData,
  122. const uint8 *pubSignature, const uint32 cubSignature,
  123. const uint8 *pubPublicKey, const uint32 cubPublicKey );
  124. static bool RSASignSHA256( const uint8 *pubData, const uint32 cubData,
  125. uint8 *pubSignature, uint32 *pcubSignature,
  126. const uint8 * pubPrivateKey, const uint32 cubPrivateKey );
  127. static bool RSAVerifySignatureSHA256( const uint8 *pubData, const uint32 cubData,
  128. const uint8 *pubSignature, const uint32 cubSignature,
  129. const uint8 *pubPublicKey, const uint32 cubPublicKey );
  130. static bool HexEncode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
  131. static bool HexDecode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData );
  132. static uint32 Base64EncodeMaxOutput( uint32 cubData, const char *pszLineBreakOrNull );
  133. static bool Base64Encode( const uint8 *pubData, uint32 cubData, char *pchEncodedData, uint32 cchEncodedData, bool bInsertLineBreaks = true ); // legacy, deprecated
  134. static bool Base64Encode( const uint8 *pubData, uint32 cubData, char *pchEncodedData, uint32 *pcchEncodedData, const char *pszLineBreak = "\n" );
  135. static uint32 Base64DecodeMaxOutput( uint32 cubData ) { return ( (cubData + 3 ) / 4) * 3 + 1; }
  136. static bool Base64Decode( const char *pchEncodedData, uint8 *pubDecodedData, uint32 *pcubDecodedData, bool bIgnoreInvalidCharacters = true ); // legacy, deprecated
  137. static bool Base64Decode( const char *pchEncodedData, uint32 cchEncodedData, uint8 *pubDecodedData, uint32 *pcubDecodedData, bool bIgnoreInvalidCharacters = true );
  138. static bool GenerateSalt( Salt_t *pSalt );
  139. static bool GenerateSHA1Digest( const uint8 *pubInput, const int cubInput, SHADigest_t *pOutDigest );
  140. static bool GenerateSaltedSHA1Digest( const char *pchInput, const Salt_t *pSalt, SHADigest_t *pOutDigest );
  141. static bool GenerateRandomBlock( uint8 *pubDest, int cubDest );
  142. static bool GenerateHMAC( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHADigest_t *pOutputDigest );
  143. static bool GenerateHMAC256( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHA256Digest_t *pOutputDigest );
  144. static bool BGeneratePasswordHash( const char *pchInput, EPasswordHashAlg hashType, const Salt_t &Salt, PasswordHash_t &OutPasswordHash );
  145. static bool BValidatePasswordHash( const char *pchInput, EPasswordHashAlg hashType, const PasswordHash_t &DigestStored, const Salt_t &Salt, PasswordHash_t *pDigestComputed );
  146. static bool BGeneratePBKDF2Hash( const char *pchInput, const Salt_t &Salt, unsigned int rounds, PasswordHash_t &OutPasswordHash );
  147. static bool BGenerateWrappedSHA1PasswordHash( const char *pchInput, const Salt_t &Salt, unsigned int rounds, PasswordHash_t &OutPasswordHash );
  148. static bool BUpgradeOrWrapPasswordHash( PasswordHash_t &InPasswordHash, EPasswordHashAlg hashTypeIn, const Salt_t &Salt, PasswordHash_t &OutPasswordHash, EPasswordHashAlg &hashTypeOut );
  149. static bool BGzipBuffer( const uint8 *pubData, uint32 cubData, CCryptoOutBuffer &bufOutput );
  150. static bool BGunzipBuffer( const uint8 *pubData, uint32 cubData, CCryptoOutBuffer &bufOutput );
  151. #ifdef DBGFLAG_VALIDATE
  152. static void ValidateStatics( CValidator &validator, const char *pchName );
  153. #endif
  154. };
  155. #else
  156. // bugbug ps3 - stub until we implement from PS3 libs
  157. class CCrypto
  158. {
  159. public:
  160. // ps3 only
  161. static bool Init();
  162. static void Shutdown();
  163. //shared
  164. static uint32 GetSymmetricEncryptedSize( uint32 cubPlaintextData );
  165. static bool SymmetricEncrypt( const uint8 * pubPlaintextData, uint32 cubPlaintextData, uint8 * pubEncryptedData, uint32 * pcubEncryptedData, const uint8 * pubKey, uint32 cubKey );
  166. static bool SymmetricDecrypt( const uint8 * pubEncryptedData, uint32 cubEncryptedData, uint8 * pubPlaintextData, uint32 * pcubPlaintextData, const uint8 * pubKey, uint32 cubKey );
  167. static bool RSAGenerateKeys( uint8 *pubPublicKey, uint32 *pcubPublicKey, uint8 *pubPrivateKey, uint32 *pcubPrivateKey ) { AssertMsg( false, "RSAGenerateKeys not implemented on PS3" ); return false; }
  168. static bool RSAEncrypt( const uint8 *pubPlaintextPlaintextData, const uint32 cubData, uint8 *pubEncryptedData, uint32 *pcubEncryptedData, const uint8 *pubPublicKey, const uint32 cubPublicKey );
  169. static bool RSADecrypt( const uint8 *pubEncryptedData, uint32 cubEncryptedData, uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubPrivateKey, const uint32 cubPrivateKey );
  170. static bool RSAPublicDecrypt_NoPadding( const uint8 *pubEncryptedData, uint32 cubEncryptedData, uint8 *pubPlaintextData, uint32 *pcubPlaintextData, const uint8 *pubPublicKey, const uint32 cubPublicKey ) { AssertMsg( false, "RSAPublicDecrypt_NoPadding not implemented on PS3" ); return false; }
  171. static bool RSASign( const uint8 *pubData, const uint32 cubData, uint8 *pubSignature, uint32 *pcubSignature, const uint8 * pubPrivateKey, const uint32 cubPrivateKey );
  172. static bool RSAVerifySignature( const uint8 *pubData, const uint32 cubData, const uint8 *pubSignature, const uint32 cubSignature, const uint8 *pubPublicKey, const uint32 cubPublicKey );
  173. static bool HexEncode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
  174. static bool HexDecode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData );
  175. static bool Base64Encode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData, bool bInsertLineBreaks = true ) { AssertMsg( false, "Base64Encode not implemented on PS3" ); return false; } // cellHttpUtilBase64Encoder()
  176. static bool Base64Decode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData, bool bIgnoreInvalidCharacters = true ) { AssertMsg( false, "Base64Decode not implemented on PS3" ); return false; } // cellHttpUtilBase64Decoder()
  177. static bool GenerateSalt( Salt_t *pSalt );
  178. static bool GenerateSHA1Digest( const uint8 *pubInput, const int cubInput, SHADigest_t *pOutDigest );
  179. static bool GenerateSaltedSHA1Digest( const char *pchInput, const Salt_t *pSalt, SHADigest_t *pOutDigest ) { AssertMsg( false, "GenerateSaltedSHA1Digest not implemented on PS3" ); return false; }
  180. static bool GenerateRandomBlock( uint8 *pubDest, int cubDest );
  181. static bool GenerateHMAC( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHADigest_t *pOutputDigest ) { AssertMsg( false, "GenerateHMAC not implemented on PS3" ); return false; }
  182. static bool GenerateHMAC256( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHA256Digest_t *pOutputDigest ) { AssertMsg( false, "GenerateHMAC256 not implemented on PS3" ); return false; }
  183. static bool BGzipBuffer( const uint8 *pubData, uint32 cubData, CCryptoOutBuffer &bufOutput );
  184. static bool BGunzipBuffer( const uint8 *pubData, uint32 cubData, CCryptoOutBuffer &bufOutput );
  185. #ifdef DBGFLAG_VALIDATE
  186. static void ValidateStatics( CValidator &validator, const char *pchName );
  187. #endif
  188. };
  189. #endif //!_PS3
  190. class CSimpleBitString;
  191. //-----------------------------------------------------------------------------
  192. // Purpose: Implement hex encoding / decoding using a custom lookup table.
  193. // This is a class because the decoding is done via a generated
  194. // reverse-lookup table, and to save time it's best to just create
  195. // that table once.
  196. //-----------------------------------------------------------------------------
  197. class CCustomHexEncoder
  198. {
  199. public:
  200. CCustomHexEncoder( const char *pchEncodingTable );
  201. ~CCustomHexEncoder();
  202. bool Encode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
  203. bool Decode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData );
  204. private:
  205. bool m_bValidEncoding;
  206. uint8 m_rgubEncodingTable[16];
  207. int m_rgnDecodingTable[256];
  208. };
  209. //-----------------------------------------------------------------------------
  210. // Purpose: Implement base32 encoding / decoding using a custom lookup table.
  211. // This is a class because the decoding is done via a generated
  212. // reverse-lookup table, and to save time it's best to just create
  213. // that table once.
  214. //-----------------------------------------------------------------------------
  215. class CCustomBase32Encoder
  216. {
  217. public:
  218. CCustomBase32Encoder( const char *pchEncodingTable );
  219. ~CCustomBase32Encoder();
  220. bool Encode( const uint8 *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
  221. bool Decode( const char *pchData, uint8 *pubDecodedData, uint32 *pcubDecodedData );
  222. bool Encode( CSimpleBitString *pBitStringData, char *pchEncodedData, uint32 cchEncodedData );
  223. bool Decode( const char *pchData, CSimpleBitString *pBitStringDecodedData );
  224. private:
  225. bool m_bValidEncoding;
  226. uint8 m_rgubEncodingTable[32];
  227. int m_rgnDecodingTable[256];
  228. };
  229. #endif // CRYPTO_H