From 4ceb300a75844e41884fc924955ba4cdf81b6895 Mon Sep 17 00:00:00 2001
From: RD42 <42702181+dashr9230@users.noreply.github.com>
Date: Sun, 4 Feb 2024 19:23:08 +0800
Subject: [PATCH] [saco/server/bot] Add and match RakNet SHA1
---
bot/bot.vcproj | 6 +
raknet/SHA1.cpp | 326 +++++++++++++++++++++++++++++++++++++++++++
raknet/SHA1.h | 85 +++++++++++
saco/saco.vcproj | 6 +
server/server.vcproj | 6 +
5 files changed, 429 insertions(+)
create mode 100644 raknet/SHA1.cpp
create mode 100644 raknet/SHA1.h
diff --git a/bot/bot.vcproj b/bot/bot.vcproj
index d3034cd..28a6d62 100644
--- a/bot/bot.vcproj
+++ b/bot/bot.vcproj
@@ -237,6 +237,12 @@
+
+
+
+
diff --git a/raknet/SHA1.cpp b/raknet/SHA1.cpp
new file mode 100644
index 0000000..2cc9228
--- /dev/null
+++ b/raknet/SHA1.cpp
@@ -0,0 +1,326 @@
+/**
+* @brief SHA-1 Hash key computation
+*
+* 100% free public domain implementation of the SHA-1
+* algorithm by Dominik Reichl
+*
+*
+* === Test Vectors (from FIPS PUB 180-1) ===
+*
+* "abc"
+* A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+*
+* "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+* 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+*
+* A million repetitions of "a"
+* 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+*/
+
+
+#include "SHA1.h"
+#include
+
+
+CSHA1::CSHA1()
+{
+ Reset();
+}
+
+CSHA1::~CSHA1()
+{
+ Reset();
+}
+
+
+void CSHA1::Reset()
+{
+ // SHA1 initialization constants
+ m_state[ 0 ] = 0x67452301;
+ m_state[ 1 ] = 0xEFCDAB89;
+ m_state[ 2 ] = 0x98BADCFE;
+ m_state[ 3 ] = 0x10325476;
+ m_state[ 4 ] = 0xC3D2E1F0;
+
+ m_count[ 0 ] = 0;
+ m_count[ 1 ] = 0;
+}
+
+void CSHA1::Transform( unsigned int state[ 5 ], unsigned char buffer[ 64 ] )
+{
+ unsigned int a = 0, b = 0, c = 0, d = 0, e = 0;
+
+ SHA1_WORKSPACE_BLOCK* block;
+ // static unsigned char workspace[64];
+ block = ( SHA1_WORKSPACE_BLOCK * ) workspace;
+ memcpy( block, buffer, 64 );
+
+ // Copy state[] to working vars
+ a = state[ 0 ];
+ b = state[ 1 ];
+ c = state[ 2 ];
+ d = state[ 3 ];
+ e = state[ 4 ];
+
+ // 4 rounds of 20 operations each. Loop unrolled.
+ R0( a, b, c, d, e, 0 );
+ R0( e, a, b, c, d, 1 );
+ R0( d, e, a, b, c, 2 );
+ R0( c, d, e, a, b, 3 );
+ R0( b, c, d, e, a, 4 );
+ R0( a, b, c, d, e, 5 );
+ R0( e, a, b, c, d, 6 );
+ R0( d, e, a, b, c, 7 );
+ R0( c, d, e, a, b, 8 );
+ R0( b, c, d, e, a, 9 );
+ R0( a, b, c, d, e, 10 );
+ R0( e, a, b, c, d, 11 );
+ R0( d, e, a, b, c, 12 );
+ R0( c, d, e, a, b, 13 );
+ R0( b, c, d, e, a, 14 );
+ R0( a, b, c, d, e, 15 );
+ R1( e, a, b, c, d, 16 );
+ R1( d, e, a, b, c, 17 );
+ R1( c, d, e, a, b, 18 );
+ R1( b, c, d, e, a, 19 );
+ R2( a, b, c, d, e, 20 );
+ R2( e, a, b, c, d, 21 );
+ R2( d, e, a, b, c, 22 );
+ R2( c, d, e, a, b, 23 );
+ R2( b, c, d, e, a, 24 );
+ R2( a, b, c, d, e, 25 );
+ R2( e, a, b, c, d, 26 );
+ R2( d, e, a, b, c, 27 );
+ R2( c, d, e, a, b, 28 );
+ R2( b, c, d, e, a, 29 );
+ R2( a, b, c, d, e, 30 );
+ R2( e, a, b, c, d, 31 );
+ R2( d, e, a, b, c, 32 );
+ R2( c, d, e, a, b, 33 );
+ R2( b, c, d, e, a, 34 );
+ R2( a, b, c, d, e, 35 );
+ R2( e, a, b, c, d, 36 );
+ R2( d, e, a, b, c, 37 );
+ R2( c, d, e, a, b, 38 );
+ R2( b, c, d, e, a, 39 );
+ R3( a, b, c, d, e, 40 );
+ R3( e, a, b, c, d, 41 );
+ R3( d, e, a, b, c, 42 );
+ R3( c, d, e, a, b, 43 );
+ R3( b, c, d, e, a, 44 );
+ R3( a, b, c, d, e, 45 );
+ R3( e, a, b, c, d, 46 );
+ R3( d, e, a, b, c, 47 );
+ R3( c, d, e, a, b, 48 );
+ R3( b, c, d, e, a, 49 );
+ R3( a, b, c, d, e, 50 );
+ R3( e, a, b, c, d, 51 );
+ R3( d, e, a, b, c, 52 );
+ R3( c, d, e, a, b, 53 );
+ R3( b, c, d, e, a, 54 );
+ R3( a, b, c, d, e, 55 );
+ R3( e, a, b, c, d, 56 );
+ R3( d, e, a, b, c, 57 );
+ R3( c, d, e, a, b, 58 );
+ R3( b, c, d, e, a, 59 );
+ R4( a, b, c, d, e, 60 );
+ R4( e, a, b, c, d, 61 );
+ R4( d, e, a, b, c, 62 );
+ R4( c, d, e, a, b, 63 );
+ R4( b, c, d, e, a, 64 );
+ R4( a, b, c, d, e, 65 );
+ R4( e, a, b, c, d, 66 );
+ R4( d, e, a, b, c, 67 );
+ R4( c, d, e, a, b, 68 );
+ R4( b, c, d, e, a, 69 );
+ R4( a, b, c, d, e, 70 );
+ R4( e, a, b, c, d, 71 );
+ R4( d, e, a, b, c, 72 );
+ R4( c, d, e, a, b, 73 );
+ R4( b, c, d, e, a, 74 );
+ R4( a, b, c, d, e, 75 );
+ R4( e, a, b, c, d, 76 );
+ R4( d, e, a, b, c, 77 );
+ R4( c, d, e, a, b, 78 );
+ R4( b, c, d, e, a, 79 );
+
+ // Add the working vars back into state[]
+ state[ 0 ] += a;
+ state[ 1 ] += b;
+ state[ 2 ] += c;
+ state[ 3 ] += d;
+ state[ 4 ] += e;
+
+ // Wipe variables
+ a = 0;
+ b = 0;
+ c = 0;
+ d = 0;
+ e = 0;
+}
+
+// Use this function to hash in binary data and strings
+void CSHA1::Update( unsigned char* data, unsigned int len )
+{
+ unsigned int i = 0, j = 0;
+
+ j = ( m_count[ 0 ] >> 3 ) & 63;
+
+ if ( ( m_count[ 0 ] += len << 3 ) < ( len << 3 ) )
+ m_count[ 1 ] ++;
+
+ m_count[ 1 ] += ( len >> 29 );
+
+ if ( ( j + len ) > 63 )
+ {
+ memcpy( &m_buffer[ j ], data, ( i = 64 - j ) );
+ Transform( m_state, m_buffer );
+
+ for ( ; i + 63 < len; i += 64 )
+ {
+ Transform( m_state, &data[ i ] );
+ }
+
+ j = 0;
+ }
+
+ else
+ i = 0;
+
+ memcpy( &m_buffer[ j ], &data[ i ], len - i );
+}
+
+// Hash in file contents
+bool CSHA1::HashFile( char *szFileName )
+{
+ unsigned long ulFileSize = 0, ulRest = 0, ulBlocks = 0;
+ unsigned long i = 0;
+ unsigned char uData[ MAX_FILE_READ_BUFFER ];
+ FILE *fIn = NULL;
+
+ if ( ( fIn = fopen( szFileName, "rb" ) ) == NULL )
+ return ( false );
+
+ fseek( fIn, 0, SEEK_END );
+
+ ulFileSize = ftell( fIn );
+
+ fseek( fIn, 0, SEEK_SET );
+
+ // This is faster
+ div_t temp;
+
+ temp = div( ulFileSize, MAX_FILE_READ_BUFFER );
+
+ ulRest = temp.rem;
+
+ ulBlocks = temp.quot;
+
+ // ulRest = ulFileSize % MAX_FILE_READ_BUFFER;
+ // ulBlocks = ulFileSize / MAX_FILE_READ_BUFFER;
+
+ for ( i = 0; i < ulBlocks; i++ )
+ {
+ fread( uData, 1, MAX_FILE_READ_BUFFER, fIn );
+ Update( uData, MAX_FILE_READ_BUFFER );
+ }
+
+ if ( ulRest != 0 )
+ {
+ fread( uData, 1, ulRest, fIn );
+ Update( uData, ulRest );
+ }
+
+ fclose( fIn );
+ fIn = NULL;
+
+ return ( true );
+}
+
+void CSHA1::Final()
+{
+ unsigned int i = 0, j = 0;
+ unsigned char finalcount[ 8 ] =
+ {
+ 0, 0, 0, 0, 0, 0, 0, 0
+ };
+
+ for ( i = 0; i < 8; i++ )
+ finalcount[ i ] = (unsigned char) ( ( m_count[ ( i >= 4 ? 0 : 1 ) ]
+ >> ( ( 3 - ( i & 3 ) ) * 8 ) ) & 255 ); // Endian independent
+
+ Update( ( unsigned char * ) "\200", 1 );
+
+ while ( ( m_count[ 0 ] & 504 ) != 448 )
+ Update( ( unsigned char * ) "\0", 1 );
+
+ Update( finalcount, 8 ); // Cause a SHA1Transform()
+
+ for ( i = 0; i < 20; i++ )
+ {
+ m_digest[ i ] = (unsigned char) ( ( m_state[ i >> 2 ] >> ( ( 3 - ( i & 3 ) ) * 8 ) ) & 255 );
+ }
+
+ // Wipe variables for security reasons
+ i = 0;
+
+ j = 0;
+
+ memset( m_buffer, 0, 64 );
+
+ memset( m_state, 0, 20 );
+
+ memset( m_count, 0, 8 );
+
+ memset( finalcount, 0, 8 );
+
+ Transform( m_state, m_buffer );
+}
+
+// Get the final hash as a pre-formatted string
+void CSHA1::ReportHash( char *szReport, unsigned char uReportType )
+{
+ unsigned char i = 0;
+ char szTemp[ 4 ];
+
+ if ( uReportType == REPORT_HEX )
+ {
+ sprintf( szTemp, "%02X", m_digest[ 0 ] );
+ strcat( szReport, szTemp );
+
+ for ( i = 1; i < 20; i++ )
+ {
+ sprintf( szTemp, " %02X", m_digest[ i ] );
+ strcat( szReport, szTemp );
+ }
+ }
+
+ else
+ if ( uReportType == REPORT_DIGIT )
+ {
+ sprintf( szTemp, "%u", m_digest[ 0 ] );
+ strcat( szReport, szTemp );
+
+ for ( i = 1; i < 20; i++ )
+ {
+ sprintf( szTemp, " %u", m_digest[ i ] );
+ strcat( szReport, szTemp );
+ }
+ }
+
+ else
+ strcpy( szReport, "Error: Unknown report type!" );
+}
+
+// Get the raw message digest
+void CSHA1::GetHash( unsigned char *uDest )
+{
+ memcpy( uDest, m_digest, 20 );
+}
+
+// Get the raw message digest
+// Added by Kevin to be quicker
+unsigned char * CSHA1::GetHash( void ) const
+{
+ return ( unsigned char * ) m_digest;
+}
diff --git a/raknet/SHA1.h b/raknet/SHA1.h
new file mode 100644
index 0000000..907a7b5
--- /dev/null
+++ b/raknet/SHA1.h
@@ -0,0 +1,85 @@
+/// \brief \b [Internal] SHA-1 computation class
+///
+/// 100% free public domain implementation of the SHA-1
+/// algorithm by Dominik Reichl
+///
+///
+/// === Test Vectors (from FIPS PUB 180-1) ===
+///
+/// "abc"
+/// A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D
+///
+/// "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+/// 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1
+///
+/// A million repetitions of "a"
+/// 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F
+
+#ifndef ___SHA1_H___
+#define ___SHA1_H___
+
+#include // Needed for file access
+#include // Needed for memset and memcpy
+#include // Needed for strcat and strcpy
+#include "Types.h"
+#include "Export.h"
+
+#define MAX_FILE_READ_BUFFER 8000
+
+#define SHA1_LENGTH 20
+
+class RAK_DLL_EXPORT CSHA1
+{
+
+public:
+ // Rotate x bits to the left
+ // #define ROL32(value, bits) (((value)<<(bits))|((value)>>(32-(bits))))
+
+#ifdef LITTLE_ENDIAN
+#define SHABLK0(i) (block->l[i] = (ROL32(block->l[i],24) & 0xFF00FF00) \
+ | (ROL32(block->l[i],8) & 0x00FF00FF))
+#else
+#define SHABLK0(i) (block->l[i])
+#endif
+
+#define SHABLK(i) (block->l[i&15] = ROL32(block->l[(i+13)&15] ^ block->l[(i+8)&15] \
+ ^ block->l[(i+2)&15] ^ block->l[i&15],1))
+
+ // SHA-1 rounds
+#define R0(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK0(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
+#define R1(v,w,x,y,z,i) { z+=((w&(x^y))^y)+SHABLK(i)+0x5A827999+ROL32(v,5); w=ROL32(w,30); }
+#define R2(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0x6ED9EBA1+ROL32(v,5); w=ROL32(w,30); }
+#define R3(v,w,x,y,z,i) { z+=(((w|x)&y)|(w&x))+SHABLK(i)+0x8F1BBCDC+ROL32(v,5); w=ROL32(w,30); }
+#define R4(v,w,x,y,z,i) { z+=(w^x^y)+SHABLK(i)+0xCA62C1D6+ROL32(v,5); w=ROL32(w,30); }
+
+ typedef union {
+ unsigned char c[ 64 ];
+ unsigned int l[ 16 ];
+ } SHA1_WORKSPACE_BLOCK;
+ /* Two different formats for ReportHash(...)
+ */
+ enum { REPORT_HEX = 0,
+ REPORT_DIGIT = 1};
+
+ CSHA1();
+ virtual ~CSHA1();
+
+ unsigned int m_state[ 5 ];
+ unsigned int m_count[ 2 ];
+ unsigned char m_buffer[ 64 ];
+ unsigned char m_digest[ 20 ];
+ void Reset();
+ void Update( unsigned char* data, unsigned int len );
+ bool HashFile( char *szFileName );
+ void Final();
+ void ReportHash( char *szReport, unsigned char uReportType = REPORT_HEX );
+ void GetHash( unsigned char *uDest );
+ unsigned char * GetHash( void ) const;
+
+private:
+ void Transform( unsigned int state[ 5 ], unsigned char buffer[ 64 ] );
+ unsigned char workspace[ 64 ];
+};
+
+#endif // ___SHA1_H___
+
diff --git a/saco/saco.vcproj b/saco/saco.vcproj
index b90c1ae..cb8638a 100644
--- a/saco/saco.vcproj
+++ b/saco/saco.vcproj
@@ -356,6 +356,12 @@
+
+
+
+
diff --git a/server/server.vcproj b/server/server.vcproj
index 3a249d9..4fba585 100644
--- a/server/server.vcproj
+++ b/server/server.vcproj
@@ -214,6 +214,12 @@
+
+
+
+