sha1.c

Go to the documentation of this file.
00001 /*
00002  *  Copyright(C) 2006 Cameron Rich
00003  *
00004  *  This library is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU Lesser General Public License as published by
00006  *  the Free Software Foundation; either version 2.1 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This library is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU Lesser General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU Lesser General Public License
00015  *  along with this library; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00017  */
00018 
00019 /**
00020  * SHA1 implementation - as defined in FIPS PUB 180-1 published April 17, 1995.
00021  * This code was originally taken from RFC3174
00022  */
00023 
00024 #include <string.h>
00025 #include "crypto.h"
00026 
00027 /*
00028  *  Define the SHA1 circular left shift macro
00029  */
00030 #define SHA1CircularShift(bits,word) \
00031                 (((word) << (bits)) | ((word) >> (32-(bits))))
00032 
00033 /* ----- static functions ----- */
00034 static void SHA1PadMessage(SHA1_CTX *ctx);
00035 static void SHA1ProcessMessageBlock(SHA1_CTX *ctx);
00036 
00037 /**
00038  * Initialize the SHA1 context 
00039  */
00040 void SHA1Init(SHA1_CTX *ctx)
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 }
00051 
00052 /**
00053  * Accepts an array of octets as the next portion of the message.
00054  */
00055 void SHA1Update(SHA1_CTX *ctx, const uint8_t *msg, int len)
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 }
00075 
00076 /**
00077  * Return the 160-bit message digest into the user's array
00078  */
00079 void SHA1Final(SHA1_CTX *ctx, uint8_t *digest)
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 }
00093 
00094 /**
00095  * Process the next 512 bits of the message stored in the array.
00096  */
00097 static void SHA1ProcessMessageBlock(SHA1_CTX *ctx)
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 }
00182 
00183 /*
00184  * According to the standard, the message must be padded to an even
00185  * 512 bits.  The first padding bit must be a '1'.  The last 64
00186  * bits represent the length of the original message.  All bits in
00187  * between should be 0.  This function will pad the message
00188  * according to those rules by filling the Message_Block array
00189  * accordingly.  It will also call the ProcessMessageBlock function
00190  * provided appropriately.  When it returns, it can be assumed that
00191  * the message digest has been computed.
00192  *
00193  * @param ctx [in, out] The SHA1 context
00194  */
00195 static void SHA1PadMessage(SHA1_CTX *ctx)
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 }

Generated on Tue Apr 6 20:00:52 2010 for gPXE by  doxygen 1.5.7.1