#ifndef CRYPTO_H
#define CRYPTO_H
#include <tier0/platform.h>
#include "crypto_constants.h"
#include "keypair.h"
BEGIN_TIER1_NAMESPACE
class CUtlBuffer;
END_TIER1_NAMESPACE
class SymmetricCryptContextBase
{
public:
SymmetricCryptContextBase();
~SymmetricCryptContextBase() { Wipe(); }
void Wipe();
protected:
void *m_ctx;
uint32 m_cbIV, m_cbTag;
};
struct ISymmetricEncryptContext
{
virtual ~ISymmetricEncryptContext() {}
virtual bool Encrypt(
const void *pPlaintextData, size_t cbPlaintextData,
const void *pIV,
void *pEncryptedDataAndTag, uint32 *pcbEncryptedDataAndTag,
const void *pAdditionalAuthenticationData, size_t cbAuthenticationData ) = 0;
};
struct ISymmetricDecryptContext
{
virtual ~ISymmetricDecryptContext() {}
virtual bool Decrypt(
const void *pEncryptedDataAndTag, size_t cbEncryptedDataAndTag,
const void *pIV,
void *pPlaintextData, uint32 *pcbPlaintextData,
const void *pAdditionalAuthenticationData, size_t cbAuthenticationData ) = 0;
};
class AES_GCM_CipherContext : public SymmetricCryptContextBase
{
public:
bool InitCipher( const void *pKey, size_t cbKey, size_t cbIV, size_t cbTag, bool bEncrypt );
};
class AES_GCM_EncryptContext final : public AES_GCM_CipherContext, public ISymmetricEncryptContext
{
public:
inline bool Init( const void *pKey, size_t cbKey, size_t cbIV, size_t cbTag )
{
return InitCipher( pKey, cbKey, cbIV, cbTag, true );
}
virtual bool Encrypt(
const void *pPlaintextData, size_t cbPlaintextData,
const void *pIV,
void *pEncryptedDataAndTag, uint32 *pcbEncryptedDataAndTag,
const void *pAdditionalAuthenticationData, size_t cbAuthenticationData ) override;
};
class AES_GCM_DecryptContext final : public AES_GCM_CipherContext, public ISymmetricDecryptContext
{
public:
inline bool Init( const void *pKey, size_t cbKey, size_t cbIV, size_t cbTag )
{
return InitCipher( pKey, cbKey, cbIV, cbTag, false );
}
virtual bool Decrypt(
const void *pEncryptedDataAndTag, size_t cbEncryptedDataAndTag,
const void *pIV,
void *pPlaintextData, uint32 *pcbPlaintextData,
const void *pAdditionalAuthenticationData, size_t cbAuthenticationData ) override;
};
namespace CCrypto
{
void Init();
bool SymmetricAuthEncryptWithIV(
const void *pPlaintextData, size_t cbPlaintextData,
const void *pIV, size_t cbIV,
void *pEncryptedDataAndTag, uint32 *pcbEncryptedDataAndTag,
const void *pKey, size_t cbKey,
const void *pAdditionalAuthenticationData, size_t cbAuthenticationData, size_t cbTag );
bool SymmetricAuthDecryptWithIV(
const void *pEncryptedDataAndTag, size_t cbEncryptedDataAndTag,
const void *pIV, size_t cbIV,
void *pPlaintextData, uint32 *pcbPlaintextData,
const void *pKey, size_t cbKey,
const void *pAdditionalAuthenticationData, size_t cbAuthenticationData, size_t cbTag );
bool HexEncode( const void *pubData, const uint32 cubData, char *pchEncodedData, uint32 cchEncodedData );
bool HexDecode( const char *pchData, void *pubDecodedData, uint32 *pcubDecodedData );
uint32 Base64EncodeMaxOutput( size_t cubData, const char *pszLineBreakOrNull );
bool Base64Encode_Legacy( const void *pubData, size_t cubData, char *pchEncodedData, size_t cchEncodedData, bool bInsertLineBreaks = true ); bool Base64Encode( const void *pubData, size_t cubData, char *pchEncodedData, uint32 *pcchEncodedData, const char *pszLineBreak = "\n" );
inline uint32 Base64DecodeMaxOutput( size_t cubData ) { return (uint32)( ( (cubData + 3 ) / 4) * 3 + 1 ); }
bool Base64Decode_Legacy( const char *pchEncodedData, void *pubDecodedData, uint32 *pcubDecodedData, bool bIgnoreInvalidCharacters = true ); bool Base64Decode( const char *pchEncodedData, size_t cchEncodedData, void *pubDecodedData, uint32 *pcubDecodedData, bool bIgnoreInvalidCharacters = true );
bool DecodeBase64ToBuf( const char *pszEncoded, uint32 cbEncoded, CUtlBuffer &buf );
const char *LocatePEMBody( const char *pchPEM, uint32 *pcch, const char *pszExpectedType );
bool DecodePEMBody( const char *pszPem, uint32 cch, CUtlBuffer &buf, const char *pszExpectedType );
void GenerateRandomBlock( void *pubDest, int cubDest );
void GenerateSHA256Digest( const void *pData, size_t cbData, SHA256Digest_t *pOutputDigest );
void GenerateHMAC256( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHA256Digest_t *pOutputDigest );
void GenerateHMAC( const uint8 *pubData, uint32 cubData, const uint8 *pubKey, uint32 cubKey, SHADigest_t *pOutputDigest );
typedef uint64_t SipHashKey_t[2];
uint64_t SipHash( const void *data, size_t cbData, const SipHashKey_t &k );
}
#endif