sha1.c File Reference

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

Go to the source code of this file.

Defines

#define SHA1CircularShift(bits, word)   (((word) << (bits)) | ((word) >> (32-(bits))))
 SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995.

Functions

static void SHA1PadMessage (SHA1_CTX *ctx)
static void SHA1ProcessMessageBlock (SHA1_CTX *ctx)
 Process the next 512 bits of the message stored in the array.
void SHA1Init (SHA1_CTX *ctx)
 Initialize the SHA1 context.
void SHA1Update (SHA1_CTX *ctx, const uint8_t *msg, int len)
 Accepts an array of octets as the next portion of the message.
void SHA1Final (SHA1_CTX *ctx, uint8_t *digest)
 Return the 160-bit message digest into the user's array.


Define Documentation

#define SHA1CircularShift ( bits,
word   )     (((word) << (bits)) | ((word) >> (32-(bits))))

SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995.

This code was originally taken from RFC3174

Definition at line 30 of file sha1.c.

Referenced by SHA1ProcessMessageBlock().


Function Documentation

static void SHA1PadMessage ( SHA1_CTX ctx  )  [static]

Definition at line 195 of file sha1.c.

References SHA1_CTX::Length_High, SHA1_CTX::Length_Low, SHA1_CTX::Message_Block, SHA1_CTX::Message_Block_Index, and SHA1ProcessMessageBlock().

Referenced by SHA1Final().

00196 {
00197     /*
00198      *  Check to see if the current message block is too small to hold
00199      *  the initial padding bits and length.  If so, we will pad the
00200      *  block, process it, and then continue padding into a second
00201      *  block.
00202      */
00203     if (ctx->Message_Block_Index > 55)
00204     {
00205         ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
00206         while(ctx->Message_Block_Index < 64)
00207         {
00208             ctx->Message_Block[ctx->Message_Block_Index++] = 0;
00209         }
00210 
00211         SHA1ProcessMessageBlock(ctx);
00212 
00213         while (ctx->Message_Block_Index < 56)
00214         {
00215             ctx->Message_Block[ctx->Message_Block_Index++] = 0;
00216         }
00217     }
00218     else
00219     {
00220         ctx->Message_Block[ctx->Message_Block_Index++] = 0x80;
00221         while(ctx->Message_Block_Index < 56)
00222         {
00223 
00224             ctx->Message_Block[ctx->Message_Block_Index++] = 0;
00225         }
00226     }
00227 
00228     /*
00229      *  Store the message length as the last 8 octets
00230      */
00231     ctx->Message_Block[56] = ctx->Length_High >> 24;
00232     ctx->Message_Block[57] = ctx->Length_High >> 16;
00233     ctx->Message_Block[58] = ctx->Length_High >> 8;
00234     ctx->Message_Block[59] = ctx->Length_High;
00235     ctx->Message_Block[60] = ctx->Length_Low >> 24;
00236     ctx->Message_Block[61] = ctx->Length_Low >> 16;
00237     ctx->Message_Block[62] = ctx->Length_Low >> 8;
00238     ctx->Message_Block[63] = ctx->Length_Low;
00239     SHA1ProcessMessageBlock(ctx);
00240 }

static void SHA1ProcessMessageBlock ( SHA1_CTX ctx  )  [static]

Process the next 512 bits of the message stored in the array.

Definition at line 97 of file sha1.c.

References SHA1_CTX::Intermediate_Hash, SHA1_CTX::Message_Block, SHA1_CTX::Message_Block_Index, and SHA1CircularShift.

Referenced by SHA1PadMessage(), and SHA1Update().

00098 {
00099     const uint32_t K[] =    {       /* Constants defined in SHA-1   */
00100                             0x5A827999,
00101                             0x6ED9EBA1,
00102                             0x8F1BBCDC,
00103                             0xCA62C1D6
00104                             };
00105     int        t;                 /* Loop counter                */
00106     uint32_t      temp;              /* Temporary word value        */
00107     uint32_t      W[80];             /* Word sequence               */
00108     uint32_t      A, B, C, D, E;     /* Word buffers                */
00109 
00110     /*
00111      *  Initialize the first 16 words in the array W
00112      */
00113     for  (t = 0; t < 16; t++)
00114     {
00115         W[t] = ctx->Message_Block[t * 4] << 24;
00116         W[t] |= ctx->Message_Block[t * 4 + 1] << 16;
00117         W[t] |= ctx->Message_Block[t * 4 + 2] << 8;
00118         W[t] |= ctx->Message_Block[t * 4 + 3];
00119     }
00120 
00121     for (t = 16; t < 80; t++)
00122     {
00123        W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
00124     }
00125 
00126     A = ctx->Intermediate_Hash[0];
00127     B = ctx->Intermediate_Hash[1];
00128     C = ctx->Intermediate_Hash[2];
00129     D = ctx->Intermediate_Hash[3];
00130     E = ctx->Intermediate_Hash[4];
00131 
00132     for (t = 0; t < 20; t++)
00133     {
00134         temp =  SHA1CircularShift(5,A) +
00135                 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
00136         E = D;
00137         D = C;
00138         C = SHA1CircularShift(30,B);
00139 
00140         B = A;
00141         A = temp;
00142     }
00143 
00144     for (t = 20; t < 40; t++)
00145     {
00146         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
00147         E = D;
00148         D = C;
00149         C = SHA1CircularShift(30,B);
00150         B = A;
00151         A = temp;
00152     }
00153 
00154     for (t = 40; t < 60; t++)
00155     {
00156         temp = SHA1CircularShift(5,A) +
00157                ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
00158         E = D;
00159         D = C;
00160         C = SHA1CircularShift(30,B);
00161         B = A;
00162         A = temp;
00163     }
00164 
00165     for (t = 60; t < 80; t++)
00166     {
00167         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
00168         E = D;
00169         D = C;
00170         C = SHA1CircularShift(30,B);
00171         B = A;
00172         A = temp;
00173     }
00174 
00175     ctx->Intermediate_Hash[0] += A;
00176     ctx->Intermediate_Hash[1] += B;
00177     ctx->Intermediate_Hash[2] += C;
00178     ctx->Intermediate_Hash[3] += D;
00179     ctx->Intermediate_Hash[4] += E;
00180     ctx->Message_Block_Index = 0;
00181 }

void SHA1Init ( SHA1_CTX ctx  ) 

Initialize the SHA1 context.

Definition at line 40 of file sha1.c.

References SHA1_CTX::Intermediate_Hash, SHA1_CTX::Length_High, SHA1_CTX::Length_Low, and SHA1_CTX::Message_Block_Index.

Referenced by sha1_init().

00041 {
00042     ctx->Length_Low             = 0;
00043     ctx->Length_High            = 0;
00044     ctx->Message_Block_Index    = 0;
00045     ctx->Intermediate_Hash[0]   = 0x67452301;
00046     ctx->Intermediate_Hash[1]   = 0xEFCDAB89;
00047     ctx->Intermediate_Hash[2]   = 0x98BADCFE;
00048     ctx->Intermediate_Hash[3]   = 0x10325476;
00049     ctx->Intermediate_Hash[4]   = 0xC3D2E1F0;
00050 }

void SHA1Update ( SHA1_CTX ctx,
const uint8_t msg,
int  len 
)

Accepts an array of octets as the next portion of the message.

Definition at line 55 of file sha1.c.

References SHA1_CTX::Length_High, SHA1_CTX::Length_Low, SHA1_CTX::Message_Block, SHA1_CTX::Message_Block_Index, and SHA1ProcessMessageBlock().

Referenced by sha1_update().

00056 {
00057     while (len--)
00058     {
00059         ctx->Message_Block[ctx->Message_Block_Index++] = (*msg & 0xFF);
00060 
00061         ctx->Length_Low += 8;
00062         if (ctx->Length_Low == 0)
00063         {
00064             ctx->Length_High++;
00065         }
00066 
00067         if (ctx->Message_Block_Index == 64)
00068         {
00069             SHA1ProcessMessageBlock(ctx);
00070         }
00071 
00072         msg++;
00073     }
00074 }

void SHA1Final ( SHA1_CTX ctx,
uint8_t digest 
)

Return the 160-bit message digest into the user's array.

Definition at line 79 of file sha1.c.

References SHA1_CTX::Intermediate_Hash, SHA1_CTX::Length_High, SHA1_CTX::Length_Low, memset(), SHA1_CTX::Message_Block, SHA1_SIZE, and SHA1PadMessage().

Referenced by sha1_final().

00080 {
00081     int i;
00082 
00083     SHA1PadMessage(ctx);
00084     memset(ctx->Message_Block, 0, 64);
00085     ctx->Length_Low = 0;    /* and clear length */
00086     ctx->Length_High = 0;
00087 
00088     for  (i = 0; i < SHA1_SIZE; i++)
00089     {
00090         digest[i] = ctx->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) );
00091     }
00092 }


Generated on Tue Apr 6 20:01:15 2010 for gPXE by  doxygen 1.5.7.1