• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) The Internet Society (2001).  All Rights Reserved.
3  *
4  * This document and translations of it may be copied and furnished to
5  * others, and derivative works that comment on or otherwise explain it
6  * or assist in its implementation may be prepared, copied, published
7  * and distributed, in whole or in part, without restriction of any
8  * kind, provided that the above copyright notice and this paragraph are
9  * included on all such copies and derivative works.  However, this
10  * document itself may not be modified in any way, such as by removing
11  * the copyright notice or references to the Internet Society or other
12  * Internet organizations, except as needed for the purpose of
13  * developing Internet standards in which case the procedures for
14  * copyrights defined in the Internet Standards process must be
15  * followed, or as required to translate it into languages other than
16  * English.
17  *
18  * The limited permissions granted above are perpetual and will not be
19  * revoked by the Internet Society or its successors or assigns.
20  *
21  * This document and the information contained herein is provided on an
22  * "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING
23  * TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING
24  * BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION
25  * HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF
26  * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
27  */
28 
29 /*
30  *  sha1.c
31  *
32  *  Description:
33  *      This file implements the Secure Hashing Algorithm 1 as
34  *      defined in FIPS PUB 180-1 published April 17, 1995.
35  *
36  *      The SHA-1, produces a 160-bit message digest for a given
37  *      data stream.  It should take about 2**n steps to find a
38  *      message with the same digest as a given message and
39  *      2**(n/2) to find any two messages with the same digest,
40  *      when n is the digest size in bits.  Therefore, this
41  *      algorithm can serve as a means of providing a
42  *      "fingerprint" for a message.
43  *
44  *  Portability Issues:
45  *      SHA-1 is defined in terms of 32-bit "words".  This code
46  *      uses <stdint.h> (included via "sha1.h" to define 32 and 8
47  *      bit unsigned integer types.  If your C compiler does not
48  *      support 32 bit unsigned integers, this code is not
49  *      appropriate.
50  *
51  *  Caveats:
52  *      SHA-1 is designed to work with messages less than 2^64 bits
53  *      long.  Although SHA-1 allows a message digest to be generated
54  *      for messages of any number of bits less than 2^64, this
55  *      implementation only works with messages with a length that is
56  *      a multiple of the size of an 8-bit character.
57  *
58  */
59 
60 #include "sha1.h"
61 
62 /*
63  *  Define the SHA1 circular left shift macro
64  */
65 #define SHA1CircularShift(bits,word) \
66                 (((word) << (bits)) | ((word) >> (32-(bits))))
67 
68 /* Local Function Prototyptes */
69 void SHA1PadMessage(SHA1Context *);
70 void SHA1ProcessMessageBlock(SHA1Context *);
71 
72 /*
73  *  SHA1Reset
74  *
75  *  Description:
76  *      This function will initialize the SHA1Context in preparation
77  *      for computing a new SHA1 message digest.
78  *
79  *  Parameters:
80  *      context: [in/out]
81  *          The context to reset.
82  *
83  *  Returns:
84  *      sha Error Code.
85  *
86  */
SHA1Reset(SHA1Context * context)87 int SHA1Reset(SHA1Context *context)
88 {
89     if (!context)
90     {
91         return shaNull;
92     }
93 
94     context->Length_Low             = 0;
95     context->Length_High            = 0;
96     context->Message_Block_Index    = 0;
97 
98     context->Intermediate_Hash[0]   = 0x67452301;
99     context->Intermediate_Hash[1]   = 0xEFCDAB89;
100     context->Intermediate_Hash[2]   = 0x98BADCFE;
101     context->Intermediate_Hash[3]   = 0x10325476;
102     context->Intermediate_Hash[4]   = 0xC3D2E1F0;
103 
104     context->Computed   = 0;
105     context->Corrupted  = 0;
106     return shaSuccess;
107 }
108 
109 /*
110  *  SHA1Result
111  *
112  *  Description:
113  *      This function will return the 160-bit message digest into the
114  *      Message_Digest array  provided by the caller.
115  *      NOTE: The first octet of hash is stored in the 0th element,
116  *            the last octet of hash in the 19th element.
117  *
118  *  Parameters:
119  *      context: [in/out]
120  *          The context to use to calculate the SHA-1 hash.
121  *      Message_Digest: [out]
122  *          Where the digest is returned.
123  *
124  *  Returns:
125  *      sha Error Code.
126  *
127  */
SHA1Result(SHA1Context * context,uint8_t Message_Digest[SHA1HashSize])128 int SHA1Result( SHA1Context *context,
129                 uint8_t Message_Digest[SHA1HashSize])
130 {
131     int i;
132 
133     if (!context || !Message_Digest)
134     {
135         return shaNull;
136     }
137 
138     if (context->Corrupted)
139     {
140         return context->Corrupted;
141     }
142 
143     if (!context->Computed)
144     {
145         SHA1PadMessage(context);
146         for(i=0; i<64; ++i)
147         {
148             /* message may be sensitive, clear it out */
149             context->Message_Block[i] = 0;
150         }
151         context->Length_Low = 0;    /* and clear length */
152         context->Length_High = 0;
153         context->Computed = 1;
154     }
155 
156     for(i = 0; i < SHA1HashSize; ++i)
157     {
158         Message_Digest[i] = context->Intermediate_Hash[i>>2]
159                             >> 8 * ( 3 - ( i & 0x03 ) );
160     }
161 
162     return shaSuccess;
163 }
164 
165 /*
166  *  SHA1Input
167  *
168  *  Description:
169  *      This function accepts an array of octets as the next portion
170  *      of the message.
171  *
172  *  Parameters:
173  *      context: [in/out]
174  *          The SHA context to update
175  *      message_array: [in]
176  *          An array of characters representing the next portion of
177  *          the message.
178  *      length: [in]
179  *          The length of the message in message_array
180  *
181  *  Returns:
182  *      sha Error Code.
183  *
184  */
SHA1Input(SHA1Context * context,const uint8_t * message_array,unsigned length)185 int SHA1Input(    SHA1Context    *context,
186                   const uint8_t  *message_array,
187                   unsigned       length)
188 {
189     if (!length)
190     {
191         return shaSuccess;
192     }
193 
194     if (!context || !message_array)
195     {
196         return shaNull;
197     }
198 
199     if (context->Computed)
200     {
201         context->Corrupted = shaStateError;
202         return shaStateError;
203     }
204 
205     if (context->Corrupted)
206     {
207          return context->Corrupted;
208     }
209     while(length-- && !context->Corrupted)
210     {
211     context->Message_Block[context->Message_Block_Index++] =
212                     (*message_array & 0xFF);
213 
214     context->Length_Low += 8;
215     if (context->Length_Low == 0)
216     {
217         context->Length_High++;
218         if (context->Length_High == 0)
219         {
220             /* Message is too long */
221             context->Corrupted = 1;
222         }
223     }
224 
225     if (context->Message_Block_Index == 64)
226     {
227         SHA1ProcessMessageBlock(context);
228     }
229 
230     message_array++;
231     }
232 
233     return shaSuccess;
234 }
235 
236 /*
237  *  SHA1ProcessMessageBlock
238  *
239  *  Description:
240  *      This function will process the next 512 bits of the message
241  *      stored in the Message_Block array.
242  *
243  *  Parameters:
244  *      None.
245  *
246  *  Returns:
247  *      Nothing.
248  *
249  *  Comments:
250  *      Many of the variable names in this code, especially the
251  *      single character names, were used because those were the
252  *      names used in the publication.
253  *
254  *
255  */
SHA1ProcessMessageBlock(SHA1Context * context)256 void SHA1ProcessMessageBlock(SHA1Context *context)
257 {
258     const uint32_t K[] =    {       /* Constants defined in SHA-1   */
259                             0x5A827999,
260                             0x6ED9EBA1,
261                             0x8F1BBCDC,
262                             0xCA62C1D6
263                             };
264     int           t;                 /* Loop counter                */
265     uint32_t      temp;              /* Temporary word value        */
266     uint32_t      W[80];             /* Word sequence               */
267     uint32_t      A, B, C, D, E;     /* Word buffers                */
268 
269     /*
270      *  Initialize the first 16 words in the array W
271      */
272     for(t = 0; t < 16; t++)
273     {
274         W[t] = context->Message_Block[t * 4] << 24;
275         W[t] |= context->Message_Block[t * 4 + 1] << 16;
276         W[t] |= context->Message_Block[t * 4 + 2] << 8;
277         W[t] |= context->Message_Block[t * 4 + 3];
278     }
279 
280     for(t = 16; t < 80; t++)
281     {
282        W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
283     }
284 
285     A = context->Intermediate_Hash[0];
286     B = context->Intermediate_Hash[1];
287     C = context->Intermediate_Hash[2];
288     D = context->Intermediate_Hash[3];
289     E = context->Intermediate_Hash[4];
290 
291     for(t = 0; t < 20; t++)
292     {
293         temp =  SHA1CircularShift(5,A) +
294                 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
295         E = D;
296         D = C;
297         C = SHA1CircularShift(30,B);
298         B = A;
299         A = temp;
300     }
301 
302     for(t = 20; t < 40; t++)
303     {
304         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
305         E = D;
306         D = C;
307         C = SHA1CircularShift(30,B);
308         B = A;
309         A = temp;
310     }
311 
312     for(t = 40; t < 60; t++)
313     {
314         temp = SHA1CircularShift(5,A) +
315                ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
316         E = D;
317         D = C;
318         C = SHA1CircularShift(30,B);
319         B = A;
320         A = temp;
321     }
322 
323     for(t = 60; t < 80; t++)
324     {
325         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
326         E = D;
327         D = C;
328         C = SHA1CircularShift(30,B);
329         B = A;
330         A = temp;
331     }
332 
333     context->Intermediate_Hash[0] += A;
334     context->Intermediate_Hash[1] += B;
335     context->Intermediate_Hash[2] += C;
336     context->Intermediate_Hash[3] += D;
337     context->Intermediate_Hash[4] += E;
338 
339     context->Message_Block_Index = 0;
340 }
341 
342 
343 /*
344  *  SHA1PadMessage
345  *
346  *  Description:
347  *      According to the standard, the message must be padded to an even
348  *      512 bits.  The first padding bit must be a '1'.  The last 64
349  *      bits represent the length of the original message.  All bits in
350  *      between should be 0.  This function will pad the message
351  *      according to those rules by filling the Message_Block array
352  *      accordingly.  It will also call the ProcessMessageBlock function
353  *      provided appropriately.  When it returns, it can be assumed that
354  *      the message digest has been computed.
355  *
356  *  Parameters:
357  *      context: [in/out]
358  *          The context to pad
359  *      ProcessMessageBlock: [in]
360  *          The appropriate SHA*ProcessMessageBlock function
361  *  Returns:
362  *      Nothing.
363  *
364  */
365 
SHA1PadMessage(SHA1Context * context)366 void SHA1PadMessage(SHA1Context *context)
367 {
368     /*
369      *  Check to see if the current message block is too small to hold
370      *  the initial padding bits and length.  If so, we will pad the
371      *  block, process it, and then continue padding into a second
372      *  block.
373      */
374     if (context->Message_Block_Index > 55)
375     {
376         context->Message_Block[context->Message_Block_Index++] = 0x80;
377         while(context->Message_Block_Index < 64)
378         {
379             context->Message_Block[context->Message_Block_Index++] = 0;
380         }
381 
382         SHA1ProcessMessageBlock(context);
383 
384         while(context->Message_Block_Index < 56)
385         {
386             context->Message_Block[context->Message_Block_Index++] = 0;
387         }
388     }
389     else
390     {
391         context->Message_Block[context->Message_Block_Index++] = 0x80;
392         while(context->Message_Block_Index < 56)
393         {
394             context->Message_Block[context->Message_Block_Index++] = 0;
395         }
396     }
397 
398     /*
399      *  Store the message length as the last 8 octets
400      */
401     context->Message_Block[56] = context->Length_High >> 24;
402     context->Message_Block[57] = context->Length_High >> 16;
403     context->Message_Block[58] = context->Length_High >> 8;
404     context->Message_Block[59] = context->Length_High;
405     context->Message_Block[60] = context->Length_Low >> 24;
406     context->Message_Block[61] = context->Length_Low >> 16;
407     context->Message_Block[62] = context->Length_Low >> 8;
408     context->Message_Block[63] = context->Length_Low;
409 
410     SHA1ProcessMessageBlock(context);
411 }
412