//========= Copyright © 2005, Valve Inc., All rights reserved. ========== // // Purpose: Implementation of SHA-1 // //============================================================================= #ifndef CHECKSUM_SHA1_H #define CHECKSUM_SHA1_H #if defined( _WIN32 ) #pragma once #endif /* 100% free public domain implementation of the SHA-1 algorithm by Dominik Reichl === Test Vectors (from FIPS PUB 180-1) === SHA1("abc") = A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D SHA1("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq") = 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 SHA1(A million repetitions of "a") = 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ #include "tier0/platform.h" #if !defined(_MINIMUM_BUILD_) #include // Needed for file access #if defined( _PS3 ) #include #else #include #endif #include // Needed for strcat and strcpy #endif // If you're compiling big endian, just comment out the following line #define SHA1_LITTLE_ENDIAN typedef union { uint8 c[64]; uint32 l[16]; } SHA1_WORKSPACE_BLOCK; // SHA1 hash const unsigned int k_cubHash = 20; const unsigned int k_cchHash = 41; // k_cubHash * 2, plus 1 for terminator #pragma pack( push, 1 ) typedef uint8 SHADigest_t[ k_cubHash ]; #pragma pack( pop ) #if !defined(_MINIMUM_BUILD_) class CSHA1 #else class Minimum_CSHA1 #endif { public: // Two different formats for ReportHash(...) enum { REPORT_HEX = 0, REPORT_DIGIT = 1 }; // Constructor and Destructor #if !defined(_MINIMUM_BUILD_) CSHA1(); virtual ~CSHA1() ; #else Minimum_CSHA1() ; ~Minimum_CSHA1() ; // no virtual destructor's in the minimal builds ! #endif unsigned int m_state[5]; unsigned int m_count[2]; uint8 m_buffer[64]; uint8 m_digest[k_cubHash]; void Reset(); // Update the hash value void Update( const void *data, unsigned int len ); #if !defined(_MINIMUM_BUILD_) bool HashFile( const char *szFileName ); #endif // Finalize hash and report void Final(); #if !defined(_MINIMUM_BUILD_) void ReportHash(char *szReport, uint8 uReportType = REPORT_HEX); #endif void GetHash(uint8 *uDest); private: // Private SHA-1 transformation void Transform(unsigned int state[5], const uint8 buffer[64]); // Member variables uint8 m_workspace[64]; SHA1_WORKSPACE_BLOCK *m_block; // SHA1 pointer to the byte array above }; #define GenerateHash( hash, pubData, cubData ) { CSHA1 sha1; sha1.Update( (byte *)pubData, cubData ); sha1.Final(); sha1.GetHash( hash ); } #if !defined(_MINIMUM_BUILD_) // hash comparison function, for use with CUtlMap/CUtlRBTree bool HashLessFunc( SHADigest_t const &lhs, SHADigest_t const &rhs ); // utility class for manipulating SHA1 hashes in their compact form struct CSHA { public: SHADigest_t m_shaDigest; CSHA() { memset( m_shaDigest, 0, k_cubHash ); } explicit CSHA( const SHADigest_t rhs ) { memcpy( m_shaDigest, rhs, k_cubHash ); } SHADigest_t &SHADigest() { return m_shaDigest; } bool operator<( const CSHA &rhs ) const { return memcmp( m_shaDigest, rhs.m_shaDigest, k_cubHash ) < 0; } bool operator==( const CSHA &rhs ) const { return memcmp( m_shaDigest, rhs.m_shaDigest, k_cubHash ) == 0; } bool operator!=( const CSHA &rhs ) const { return !(*this == rhs); } bool operator==( const SHADigest_t &rhs ) const { return memcmp( m_shaDigest, rhs, k_cubHash ) == 0; } bool operator!=( const SHADigest_t &rhs ) const { return !(*this == rhs); } CSHA &operator=( const SHADigest_t rhs ) { memcpy( m_shaDigest, rhs, k_cubHash ); return *this; } void AssignTo( SHADigest_t rhs ) const { memcpy( rhs, m_shaDigest, k_cubHash ); } }; #endif // _MINIMUM_BUILD_ #endif // CHECKSUM_SHA1_H