I wrote a C++ class to calculate the SHA1 hash of strings. It shouldn't be too hard to convert to C. There's no code in the header, so you shouldn't need it.
Code:
#include "SHAHash.hpp"
std::string SHAHash::calcSHA( std::string msg )
{
DWORD a = 0x67452301;
DWORD b = 0xefcdab89;
DWORD c = 0x98badcfe;
DWORD d = 0x10325476;
DWORD e = 0xc3d2e1f0;
DWORD w[ 80 ] = { 0 };
strToBlocks( msg );
for( DWORD i = 0; i < mNumBlocks; i += 16 )
{
DWORD oldA = a;
DWORD oldB = b;
DWORD oldC = c;
DWORD oldD = d;
DWORD oldE = e;
for( DWORD j = 0; j < 80; j++ )
{
if( j < 16 )
w[ j ] = mBlocks[ i + j ];
else
w[ j ] = rol( w[ j - 3 ] ^ w[ j - 8 ] ^
w[ j - 14 ] ^ w[ j - 16 ], 1 );
DWORD t = add( add( rol( a, 5 ), ft( j, b, c, d ) ),
add( add( e, w[ j ] ), kt( j ) ) );
e = d;
d = c;
c = rol( b, 30 );
b = a;
a = t;
}
a = add( a, oldA );
b = add( b, oldB );
c = add( c, oldC );
d = add( d, oldD );
e = add( e, oldE );
}
std::ostringstream oss;
oss<<std::hex<<std::uppercase<<a<<b<<c<<d<<e;
return oss.str( );
}
void SHAHash::strToBlocks( std::string str )
{
mNumBlocks = ( ( str.length( ) + 8 ) >> 6 ) + 1;
mBlocks.clear( );
for( DWORD i = 0; i < mNumBlocks * 16; i++ )
mBlocks.push_back( i );
for( DWORD i = 0; i < mNumBlocks * 16; i++ ) mBlocks[ i ] = 0;
for( DWORD i = 0; i < str.length( ); i++ )
mBlocks[ i >> 2 ] |= str[ i ] << ( 24 - ( i % 4 ) * 8 );
mBlocks[ str.length( ) >> 2 ] |= 0x80 << ( 24 - ( str.length( ) % 4 ) * 8 );
mBlocks[ mNumBlocks * 16 - 1 ] = str.length( ) * 8;
}
DWORD SHAHash::add( DWORD x, DWORD y )
{
DWORD lsw = ( x & 0xffff ) + ( y & 0xffff );
DWORD msw = ( x >> 16 ) + ( y >> 16 ) + ( lsw >> 16 );
return ( msw << 16 ) | ( lsw & 0xffff );
}
DWORD SHAHash::rol( DWORD num, int count )
{
return ( num << count ) | ( num >> ( 32 - count ) );
}
DWORD SHAHash::ft( DWORD i, DWORD b, DWORD c, DWORD d )
{
if( i < 20 ) return ( b & c ) | ( ( ~b ) & d );
if( i < 40 ) return ( b ^ c ^ d );
if( i < 60 ) return ( b & c ) | ( b & d ) | ( c & d );
return b ^ c ^ d;
}
DWORD SHAHash::kt( DWORD i )
{
if( i < 20 ) return 0x5a827999;
if( i < 40 ) return 0x6ed9eba1;
if( i < 60 ) return 0x8f1bbcdc;
return 0xca62c1d6;
}
SHAHash::SHAHash( void )
{
}
SHAHash::~SHAHash( void )
{
}