Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

how to prevent SHA1 from crashing when encounter 0x00?

Posted on 2004-11-18
18
Medium Priority
?
404 Views
Last Modified: 2012-05-05
i have a problem here.... i have SHA1 code which produces valid results but when it encounters 0x00 or null character, it terminates... how do i make it so that it wont terminate when encounter the 0x00 ?
0
Comment
Question by:harsher
  • 8
  • 6
  • 4
18 Comments
 
LVL 45

Expert Comment

by:sunnycoder
ID: 12622562
Where is the input coming from? -- Encounters 0x00 while reading from file? If yes, did you open the file in binary mode? How are you reading from the file?

Your question title says crash while question body says terminates ... both are vastly different !!!

You need to elaborate a bit more about your problem.
0
 

Author Comment

by:harsher
ID: 12622658
ok..... my program code is in vb, it will extract data from a file using binary mode and store it in a string variable, then i will pass the whole string to the dos SHA1 program for it to calculate.

when the SHA program saw the 0x00 in the input string, it terminates.

how do i prevent the SHA program to terminate when saw the 0x00 ? the SHA program is in C code
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 12622806
How are you treating the code in the string variable? 0x00 would normally signify end of string in C. Pass another parameter - length of input to the C code. Change the loop and/or function calls in the C code to use the length number of characters as input rather than terminate on End Of String.
0
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
LVL 16

Expert Comment

by:PaulCaswell
ID: 12623078
Sounds to me like its the C program thats at fault. It should either read the file as binary or hex. Do you have sources to it? If so, check it isnt expecting hex. If you dont have sources, let use know. I have some source you could use.

Paul
0
 

Author Comment

by:harsher
ID: 12631860
in the SHA program, i have int main (int inputlen, char *inputstring)

but i can only pass in the string... but cant pass in the inputlen, not sure why....

i open the file using binary method in vb and grab the data out and send to the SHA program but it terminates upon reaching 0x00

i do have source code, have to compile it b4 i get the SHA.exe
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 12642612
>>int main (int inputlen, char *inputstring)
This wont work.

Post your code! We'll take a look.

Or request working code. I have some.

Paul
0
 

Author Comment

by:harsher
ID: 12650869
int main(int InputArg, char* InputString[])
{
    SHA1Context sha;
    int i,j, err;
      char OutputString[62], temp[20];
    uint8_t Message_Digest[20];
      j=0;
      strcpy(OutputString,"");
      strcpy(temp,"");
      err = SHA1Reset(&sha);
      err = SHA1Input(&sha,(const unsigned char *) InputString[1],strlen(InputString[1]));
      err = SHA1Result(&sha, Message_Digest);
      for(i = 0; i < 20 ; ++i)
            {
                        j += sprintf(&(OutputString[j]),"%02X ",Message_Digest[i]);
            }
      printf ("%s",OutputString);
      printf("%d",strlen(InputString[0])); //this is for debugging purposes
      printf(" %d",strlen(InputString[1])); //this is for debugging purposes
      //printf(" %d",strlen(InputString[2])); //this is for debugging purposes
      printf(" %d",InputArg); //this is for debugging purposes
    return 0;
}

can i have some codes on how to fix it?
0
 
LVL 45

Expert Comment

by:sunnycoder
ID: 12652430
hi Harsher,

int main(int InputArg, char* InputString[])

has to be

int main(int argc, char* argv[])

argc is the number of arguments (note number of arguments and not an argument)

argv is a null terminated array of all arguments

sha.exe 45 "string of 45 characters ....."

would be received in main as
argc=2
argv[0] -> "sha.exe"
argv[1] -> "45"
argv[2] -> "string of 45 characters ....."

note argv[1] is a string and needs to be converted to integer before you can use it.

Do not use str family of functions ... str family of functions treat string as NULL terminated array of chars and hence will give incorrect results ... use memcpy, memmove etc

This is not the complete source code ... I would suggest getting it from Paul as it will save you work ... If you still insist on doing it on your own, make the above modifications and if it does not work, post the entire source code for sha.

cheers
sunnycoder
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 12655853
Harsher,

You have two choices:

1. Pass the string to be hashed in HEX and convert it back to binary in the C code.

2. Pass the data to the C program in a temporary file.

If your string is likely to be less than 128 characters then the first option might be the easiest.

Anything arger than 128 would be best to be passed with a temporary file.

Let me know which and I'll help you out.

Paul
0
 

Author Comment

by:harsher
ID: 12661319
thanx for helping..... the data i have to pass in varies from few hundred chars to few thousand chars.

since the str family cannot be used.... and i dont know how to use the memcpy, memmove functions, can any of u show me the sample code?

i was thinking of read from the temp file also.... but will it stop reading once it read the 0x00 null character?

i will increase the points............
0
 
LVL 45

Assisted Solution

by:sunnycoder
sunnycoder earned 200 total points
ID: 12662228
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 12663205
Sounds to me like its the temporary file route you want. Use something like:

int main( int argc, char *argv[] )
{
      if ( argc == 1 )
      {
            FILE * f = fopen ( argv[1], "rb" );

            if ( f != NULL )
            {
                  struct SHA1_Context ctx;
                  byte sha1sum[SHA1HashSize], buffer[1000];
                  char output[41];
                  int count = 0;
                  int j;

                  SHA1_Starts( &ctx );

                  while ( (count = fread ( buffer, 1, sizeof(buffer), f )) > 0 )
                  {
                        SHA1_Update( &ctx, (byte *) buffer, count );
                  }
                  // Thats it!
                  SHA1_Finish( &ctx, sha1sum );

                  // Decode the result into hex.
                  for( j = 0; j < SHA1HashSize; j++ )
                  {
                        sprintf( output + j * 2, "%02x", sha1sum[j] );
                  }

                  // Report the result.
                  printf( "%s", sha1sum );
                  fclose (f);
            }
      }
   return( 0 );
}
0
 

Author Comment

by:harsher
ID: 12663520
thanx for the links n codes... but in the code... i dont have sha1_starts, sha1_update, sha1_finish............ i only got sha1reset, sha1input, sha1result. here is the full codings

sha1.c

#include "sha1.h"
#define SHA1CircularShift(bits,word) \
                (((word) << (bits)) | ((word) >> (32-(bits))))
void SHA1PadMessage(SHA1Context *);
void SHA1ProcessMessageBlock(SHA1Context *);

int SHA1Reset(SHA1Context *context)
{
    if (!context)
    {
        return shaNull;
    }

    context->Length_Low             = 0;
    context->Length_High            = 0;
    context->Message_Block_Index    = 0;

    context->Intermediate_Hash[0]   = 0x67452301;
    context->Intermediate_Hash[1]   = 0xEFCDAB89;
    context->Intermediate_Hash[2]   = 0x98BADCFE;
    context->Intermediate_Hash[3]   = 0x10325476;
    context->Intermediate_Hash[4]   = 0xC3D2E1F0;

    context->Computed   = 0;
    context->Corrupted  = 0;

    return shaSuccess;
}

int SHA1Result( SHA1Context *context,
                uint8_t Message_Digest[SHA1HashSize])
{
    int i;

    if (!context || !Message_Digest)
    {
        return shaNull;
    }

    if (context->Corrupted)
    {
        return context->Corrupted;
    }

    if (!context->Computed)
    {
        SHA1PadMessage(context);
        for(i=0; i<64; ++i)
        {
            /* message may be sensitive, clear it out */
            context->Message_Block[i] = 0;
        }
        context->Length_Low = 0;    /* and clear length */
        context->Length_High = 0;
        context->Computed = 1;

    }

    for(i = 0; i < SHA1HashSize; ++i)
    {
        Message_Digest[i] = context->Intermediate_Hash[i>>2]
                            >> 8 * ( 3 - ( i & 0x03 ) );
    }

    return shaSuccess;
}

int SHA1Input(    SHA1Context    *context,
                  const uint8_t  *message_array,
                  unsigned       length)
{
    if (!length)
    {
        return shaSuccess;
    }

    if (!context || !message_array)
    {
        return shaNull;
    }

    if (context->Computed)
    {
        context->Corrupted = shaStateError;

        return shaStateError;
    }

    if (context->Corrupted)
    {
         return context->Corrupted;
    }
    while(length-- && !context->Corrupted)
    {
    context->Message_Block[context->Message_Block_Index++] =
                    (*message_array & 0xFF);

    context->Length_Low += 8;
    if (context->Length_Low == 0)
    {
        context->Length_High++;
        if (context->Length_High == 0)
        {
            /* Message is too long */
            context->Corrupted = 1;
        }
    }

    if (context->Message_Block_Index == 64)
    {
        SHA1ProcessMessageBlock(context);
    }

    message_array++;
    }

    return shaSuccess;
}


void SHA1ProcessMessageBlock(SHA1Context *context)
{
    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
                            0x5A827999,
                            0x6ED9EBA1,
                            0x8F1BBCDC,
                            0xCA62C1D6
                            };
    int           t;                 /* Loop counter                */
    uint32_t      temp;              /* Temporary word value        */
    uint32_t      W[80];             /* Word sequence               */
    uint32_t      A, B, C, D, E;     /* Word buffers                */

    /*
     *  Initialize the first 16 words in the array W
     */
    for(t = 0; t < 16; t++)
    {
        W[t] = context->Message_Block[t * 4] << 24;
        W[t] |= context->Message_Block[t * 4 + 1] << 16;
        W[t] |= context->Message_Block[t * 4 + 2] << 8;
        W[t] |= context->Message_Block[t * 4 + 3];
    }

    for(t = 16; t < 80; t++)
    {
       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    }

    A = context->Intermediate_Hash[0];
    B = context->Intermediate_Hash[1];
    C = context->Intermediate_Hash[2];
    D = context->Intermediate_Hash[3];
    E = context->Intermediate_Hash[4];

    for(t = 0; t < 20; t++)
    {
        temp =  SHA1CircularShift(5,A) +
                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);

        B = A;
        A = temp;
    }

    for(t = 20; t < 40; t++)
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 40; t < 60; t++)
    {
        temp = SHA1CircularShift(5,A) +
               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    for(t = 60; t < 80; t++)
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }

    context->Intermediate_Hash[0] += A;
    context->Intermediate_Hash[1] += B;
    context->Intermediate_Hash[2] += C;
    context->Intermediate_Hash[3] += D;
    context->Intermediate_Hash[4] += E;

    context->Message_Block_Index = 0;
}

void SHA1PadMessage(SHA1Context *context)
{
    /*
     *  Check to see if the current message block is too small to hold
     *  the initial padding bits and length.  If so, we will pad the
     *  block, process it, and then continue padding into a second
     *  block.
     */
    if (context->Message_Block_Index > 55)
    {
        context->Message_Block[context->Message_Block_Index++] = 0x80;
        while(context->Message_Block_Index < 64)
        {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }

        SHA1ProcessMessageBlock(context);

        while(context->Message_Block_Index < 56)
        {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }
    }
    else
    {
        context->Message_Block[context->Message_Block_Index++] = 0x80;
        while(context->Message_Block_Index < 56)
        {

            context->Message_Block[context->Message_Block_Index++] = 0;
        }
    }

    /*
     *  Store the message length as the last 8 octets
     */
    context->Message_Block[56] = context->Length_High >> 24;
    context->Message_Block[57] = context->Length_High >> 16;
    context->Message_Block[58] = context->Length_High >> 8;
    context->Message_Block[59] = context->Length_High;
    context->Message_Block[60] = context->Length_Low >> 24;
    context->Message_Block[61] = context->Length_Low >> 16;
    context->Message_Block[62] = context->Length_Low >> 8;
    context->Message_Block[63] = context->Length_Low;

    SHA1ProcessMessageBlock(context);
}


sha1test.c

#include <stdio.h>
#include <string.h>
#include "sha1.h"

/*
 *  Define patterns for testing
 */


int main(int InputArg, char* InputString[])
{
    SHA1Context sha;
    int i,j, err;
      char OutputString[62], temp[20];
    uint8_t Message_Digest[20];
      j=0;
      strcpy(OutputString,"");
      strcpy(temp,"");
      err = SHA1Reset(&sha);
      err = SHA1Input(&sha,(const unsigned char *) InputString[1],strlen(InputString[1]));
      err = SHA1Result(&sha, Message_Digest);
      for(i = 0; i < 20 ; ++i)
            {
                        j += sprintf(&(OutputString[j]),"%02X ",Message_Digest[i]);
            }
      printf ("%s",OutputString);
      printf("%d",strlen(InputString[0]));
      printf(" %d",strlen(InputString[1]));
      //printf(" %d",strlen(InputString[2]));
      printf(" %d",InputArg);
    return 0;
}


sha1.h

#ifndef _SHA1_H_
#define _SHA1_H_
typedef unsigned char            uint8_t;
typedef unsigned int            uint32_t;
typedef int                  int_least16_t;

#ifndef _SHA_enum_
#define _SHA_enum_
enum
{
    shaSuccess = 0,
    shaNull,            /* Null pointer parameter */
    shaInputTooLong,    /* input data too long */
    shaStateError       /* called Input after Result */
};
#endif
#define SHA1HashSize 20
typedef struct SHA1Context
{
    uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest  */

    uint32_t Length_Low;            /* Message length in bits      */
    uint32_t Length_High;           /* Message length in bits      */

                               /* Index into message block array   */
    int_least16_t Message_Block_Index;
    uint8_t Message_Block[64];      /* 512-bit message blocks      */

    int Computed;               /* Is the digest computed?         */
    int Corrupted;             /* Is the message digest corrupted? */
} SHA1Context;
int SHA1Reset(  SHA1Context *);
int SHA1Input(  SHA1Context *,
                const uint8_t *,
                unsigned int);
int SHA1Result( SHA1Context *,
                uint8_t Message_Digest[SHA1HashSize]);

#endif
0
 
LVL 16

Expert Comment

by:PaulCaswell
ID: 12664189
It looks like your implementation of SHA1 is slightly different to mine.

It should be easy to change to fit.

E.G. for SHA1_Context use SHA1Context etc.

Just make the obvious changes. If you have a problem, let me know and I'll post my SHA1 implementation but it should be obvious.

Paul
0
 

Author Comment

by:harsher
ID: 12671401
hi there..... got problem with ur code....

C:\software\SHA1\sha1test.c(41) : error C2065: 'byte' : undeclared identifier

0
 

Author Comment

by:harsher
ID: 12671484
i replce the byte with char but the program still not giving me correct resutl.. can i try ur program?
0
 
LVL 16

Accepted Solution

by:
PaulCaswell earned 200 total points
ID: 12672964
byte is unsigned char.

You are welcome to use my code. It will not do exactly what you want. It is based on a public-domain module but has been 'adjusted' to work in a 16bit MSDOS environment.

/*
 * FIPS 180-1 compliant SHA-1 implementation,
 * by Christophe Devine <devine@cr0.net>;
 * this program is licensed under the GPL.
 */

//#define TEST

#include <io.h>
#include <stdio.h>
#include <fcntl.h>

#include "bool.h"
#include "CDefs.h"
DEBUG

#include <string.h>
#include "sha1.h"


// Current context for the hash.
struct SHA1_Context
{
    ulong total[2];
    ulong state[5];
    byte buffer[64];
};

// Get an unsigned 32bit integer from a byte stream in an endian indcependent way.
#define GET_UINT32(n,b,i)                                       \
{                                                               \
    (n) = (ulong) ((byte *) b)[(i)+3]                         \
      | (((ulong) ((byte *) b)[(i)+2]) <<  8)                 \
      | (((ulong) ((byte *) b)[(i)+1]) << 16)                 \
      | (((ulong) ((byte *) b)[(i)]  ) << 24);                \
}

// And its reverse.
#define PUT_UINT32(n,b,i)                                       \
{                                                               \
    (((byte *) b)[(i)+3]) = (byte) (((n)      ) & 0xFF);      \
    (((byte *) b)[(i)+2]) = (byte) (((n) >>  8) & 0xFF);      \
    (((byte *) b)[(i)+1]) = (byte) (((n) >> 16) & 0xFF);      \
    (((byte *) b)[(i)]  ) = (byte) (((n) >> 24) & 0xFF);      \
}

// Prepare the context.
static void SHA1_Starts( struct SHA1_Context *ctx )
{
    ctx->total[0] = 0;
    ctx->total[1] = 0;
    ctx->state[0] = 0x67452301;
    ctx->state[1] = 0xEFCDAB89;
    ctx->state[2] = 0x98BADCFE;
    ctx->state[3] = 0x10325476;
    ctx->state[4] = 0xC3D2E1F0;
}

// Process a block.
static void SHA1_Process( struct SHA1_Context *ctx, byte data[64] )
{
    ulong temp, A, B, C, D, E, W[16];

      // See SHA-1 algorithm.
    GET_UINT32( W[0],  data,  0 );
    GET_UINT32( W[1],  data,  4 );
    GET_UINT32( W[2],  data,  8 );
    GET_UINT32( W[3],  data, 12 );
    GET_UINT32( W[4],  data, 16 );
    GET_UINT32( W[5],  data, 20 );
    GET_UINT32( W[6],  data, 24 );
    GET_UINT32( W[7],  data, 28 );
    GET_UINT32( W[8],  data, 32 );
    GET_UINT32( W[9],  data, 36 );
    GET_UINT32( W[10], data, 40 );
    GET_UINT32( W[11], data, 44 );
    GET_UINT32( W[12], data, 48 );
    GET_UINT32( W[13], data, 52 );
    GET_UINT32( W[14], data, 56 );
    GET_UINT32( W[15], data, 60 );

#define S(x,n) ((x << n) | ((x & 0xFFFFFFFF) >> (32 - n)))

#define R(t)                                            \
(                                                       \
    temp = W[(t -  3) & 0x0F] ^ W[(t - 8) & 0x0F] ^     \
           W[(t - 14) & 0x0F] ^ W[ t      & 0x0F],      \
    ( W[t & 0x0F] = S(temp,1) )                         \
)

#define P(a,b,c,d,e,x)                                  \
{                                                       \
    e += S(a,5) + F(b,c,d) + K + x; b = S(b,30);        \
}

    A = ctx->state[0];
    B = ctx->state[1];
    C = ctx->state[2];
    D = ctx->state[3];
    E = ctx->state[4];

#define F(x,y,z) (z ^ (x & (y ^ z)))
#define K 0x5A827999

    P( A, B, C, D, E, W[0]  );
    P( E, A, B, C, D, W[1]  );
    P( D, E, A, B, C, W[2]  );
    P( C, D, E, A, B, W[3]  );
    P( B, C, D, E, A, W[4]  );
    P( A, B, C, D, E, W[5]  );
    P( E, A, B, C, D, W[6]  );
    P( D, E, A, B, C, W[7]  );
    P( C, D, E, A, B, W[8]  );
    P( B, C, D, E, A, W[9]  );
    P( A, B, C, D, E, W[10] );
    P( E, A, B, C, D, W[11] );
    P( D, E, A, B, C, W[12] );
    P( C, D, E, A, B, W[13] );
    P( B, C, D, E, A, W[14] );
    P( A, B, C, D, E, W[15] );
    P( E, A, B, C, D, R(16) );
    P( D, E, A, B, C, R(17) );
    P( C, D, E, A, B, R(18) );
    P( B, C, D, E, A, R(19) );

#undef K
#undef F

#define F(x,y,z) (x ^ y ^ z)
#define K 0x6ED9EBA1

    P( A, B, C, D, E, R(20) );
    P( E, A, B, C, D, R(21) );
    P( D, E, A, B, C, R(22) );
    P( C, D, E, A, B, R(23) );
    P( B, C, D, E, A, R(24) );
    P( A, B, C, D, E, R(25) );
    P( E, A, B, C, D, R(26) );
    P( D, E, A, B, C, R(27) );
    P( C, D, E, A, B, R(28) );
    P( B, C, D, E, A, R(29) );
    P( A, B, C, D, E, R(30) );
    P( E, A, B, C, D, R(31) );
    P( D, E, A, B, C, R(32) );
    P( C, D, E, A, B, R(33) );
    P( B, C, D, E, A, R(34) );
    P( A, B, C, D, E, R(35) );
    P( E, A, B, C, D, R(36) );
    P( D, E, A, B, C, R(37) );
    P( C, D, E, A, B, R(38) );
    P( B, C, D, E, A, R(39) );

#undef K
#undef F

#define F(x,y,z) ((x & y) | (z & (x | y)))
#define K 0x8F1BBCDC

    P( A, B, C, D, E, R(40) );
    P( E, A, B, C, D, R(41) );
    P( D, E, A, B, C, R(42) );
    P( C, D, E, A, B, R(43) );
    P( B, C, D, E, A, R(44) );
    P( A, B, C, D, E, R(45) );
    P( E, A, B, C, D, R(46) );
    P( D, E, A, B, C, R(47) );
    P( C, D, E, A, B, R(48) );
    P( B, C, D, E, A, R(49) );
    P( A, B, C, D, E, R(50) );
    P( E, A, B, C, D, R(51) );
    P( D, E, A, B, C, R(52) );
    P( C, D, E, A, B, R(53) );
    P( B, C, D, E, A, R(54) );
    P( A, B, C, D, E, R(55) );
    P( E, A, B, C, D, R(56) );
    P( D, E, A, B, C, R(57) );
    P( C, D, E, A, B, R(58) );
    P( B, C, D, E, A, R(59) );

#undef K
#undef F

#define F(x,y,z) (x ^ y ^ z)
#define K 0xCA62C1D6

    P( A, B, C, D, E, R(60) );
    P( E, A, B, C, D, R(61) );
    P( D, E, A, B, C, R(62) );
    P( C, D, E, A, B, R(63) );
    P( B, C, D, E, A, R(64) );
    P( A, B, C, D, E, R(65) );
    P( E, A, B, C, D, R(66) );
    P( D, E, A, B, C, R(67) );
    P( C, D, E, A, B, R(68) );
    P( B, C, D, E, A, R(69) );
    P( A, B, C, D, E, R(70) );
    P( E, A, B, C, D, R(71) );
    P( D, E, A, B, C, R(72) );
    P( C, D, E, A, B, R(73) );
    P( B, C, D, E, A, R(74) );
    P( A, B, C, D, E, R(75) );
    P( E, A, B, C, D, R(76) );
    P( D, E, A, B, C, R(77) );
    P( C, D, E, A, B, R(78) );
    P( B, C, D, E, A, R(79) );

#undef K
#undef F

    ctx->state[0] += A;
    ctx->state[1] += B;
    ctx->state[2] += C;
    ctx->state[3] += D;
    ctx->state[4] += E;
}

// Breaks down a block of any size into processable 64byte blocks for SHA1Process.
static void SHA1_Update( struct SHA1_Context *ctx, byte *input, ulong length )
{
    ulong left,fill;

    if( ! length ) return;

      // Force it to 0-64
    left = ( ctx->total[0] >> 3 ) & 0x3F;
      // How muct to pad.
    fill = 64 - left;

    ctx->total[0] += length <<  3;
    ctx->total[1] += length >> 29;

    ctx->total[0] &= 0xFFFFFFFF;
    ctx->total[1] += ctx->total[0] < ( length << 3 );

    if( left && length >= fill )
    {
        memcpy( (void *) (ctx->buffer + left), (void *) input, (ushort)fill );
        SHA1_Process( ctx, ctx->buffer );
        length -= fill;
        input  += fill;
        left = 0;
    }

    while( length >= 64 )
    {
        SHA1_Process( ctx, input );
        length -= 64;
        input  += 64;
    }

    if( length )
    {
        memcpy( (void *) (ctx->buffer + left), (void *) input, (ushort)length );
    }
}

// How to pad a block if it isnt 64 bytes in length.
static byte SHA1_Padding[64] =
{
 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
};

// Finished. Round up lengths etc if necessary.
static void SHA1_Finish( struct SHA1_Context *ctx, byte digest[SHA1HashSize] )
{
    ulong last, padn;
    byte msglen[8];

    PUT_UINT32( ctx->total[1], msglen, 0 );
    PUT_UINT32( ctx->total[0], msglen, 4 );

    last = ( ctx->total[0] >> 3 ) & 0x3F;
    padn = ( last < 56 ) ? ( 56 - last ) : ( 120 - last );

    SHA1_Update( ctx, SHA1_Padding, padn );
    SHA1_Update( ctx, msglen, 8 );

    PUT_UINT32( ctx->state[0], digest,  0 );
    PUT_UINT32( ctx->state[1], digest,  4 );
    PUT_UINT32( ctx->state[2], digest,  8 );
    PUT_UINT32( ctx->state[3], digest, 12 );
    PUT_UINT32( ctx->state[4], digest, 16 );
}

// Storage.
static struct SHA1_Context sha;

// Rest the CRC system.
void SHA1Start (void)
{
    SHA1_Starts(&sha);
}

// Evaluate the result.
char * SHA1Finish (void)
{
      static char result[SHA1HashSize*2 +1];
    byte digest[SHA1HashSize];
      int i;
      // Get the digest.
    SHA1_Finish(&sha, digest);
      // Convert to hex.
      for ( i = 0; i < SHA1HashSize; i++ )
      {
            sprintf(&result[2*i],"%02.2x", digest[i]);
      }
      return result;
}

// Calculate the CRC.
void SHA1Block ( byte * data, int length )
{
      // Add the crc.
      SHA1_Update(&sha, data, length);
}

#ifdef TEST

#include <stdlib.h>
#include <stdio.h>

/*
 * these are the standard FIPS 180-1 test vectors
 */

static char *msg[] =
{
    "abc",
    "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq",
    NULL
};

static char *val[] =
{
      //"abc"
    "a9993e364706816aba3e25717850c26c9cd0d89d",
      //"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
    "84983e441c3bd26ebaae4aa1f95129e5e54670f1",
      // One million 'a's.
    "34aa973cd4c4daa4f61eeb2bdbad27316534016f"
};

// Run through the standard tests.
int main( int argc, char *argv[] )
{
    int i, j;
    char output[41];
    struct SHA1_Context ctx;
    byte sha1sum[SHA1HashSize], buffer[1000];

    for( i = 0; i < 3; i++ )
    {
        SHA1_Starts( &ctx );

        if( i < 2 )
        {
                  // Use the message from the array.
            SHA1_Update( &ctx, (byte *) msg[i], strlen( msg[i] ) );
        }
        else
        {
                  // Use 1,000,000 'a's
            memset( buffer, 'a', 1000 );

            for( j = 0; j < 1000; j++ )
            {
                SHA1_Update( &ctx, (byte *) buffer, 1000 );
            }
        }

            // Thats it!
        SHA1_Finish( &ctx, sha1sum );

            // Decode the result into hex.
        for( j = 0; j < SHA1HashSize; j++ )
        {
            sprintf( output + j * 2, "%02x", sha1sum[j] );
        }

            // Report the result.
        printf( "test %d ", i + 1 );

            // Same?
        if( ! memcmp( output, val[i], 40 ) )
        {
            printf( "passed\n" );
        }
        else
        {
            printf( "failed (%s != %s)\n", output, val[i] );
        }
    }
    return( 0 );
}

#endif

0
 

Author Comment

by:harsher
ID: 12678119
thanx for the code dude...... will add more points then split it up between u guys....
0

Featured Post

Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This tutorial is posted by Aaron Wojnowski, administrator at SDKExpert.net.  To view more iPhone tutorials, visit www.sdkexpert.net. This is a very simple tutorial on finding the user's current location easily. In this tutorial, you will learn ho…
Examines three attack vectors, specifically, the different types of malware used in malicious attacks, web application attacks, and finally, network based attacks.  Concludes by examining the means of securing and protecting critical systems and inf…
The goal of this video is to provide viewers with basic examples to understand recursion in the C programming language.
The goal of this video is to provide viewers with basic examples to understand and use conditional statements in the C programming language.
Suggested Courses

810 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question