]> git.sur5r.net Git - bacula/bacula/blob - bacula/src/lib/sha1.c
Apply Preben 'Peppe' Guldberg <peppe@wielders.org>
[bacula/bacula] / bacula / src / lib / sha1.c
1 /*
2  *  sha1.c
3  *
4  *  Description:
5  *      This file implements the Secure Hashing Algorithm 1 as
6  *      defined in FIPS PUB 180-1 published April 17, 1995.
7  *
8  *      The SHA-1, produces a 160-bit message digest for a given
9  *      data stream.  It should take about 2**n steps to find a
10  *      message with the same digest as a given message and
11  *      2**(n/2) to find any two messages with the same digest,
12  *      when n is the digest size in bits.  Therefore, this
13  *      algorithm can serve as a means of providing a
14  *      "fingerprint" for a message.
15  *
16  *  Portability Issues:
17  *      SHA-1 is defined in terms of 32-bit "words".  This code
18  *      uses <stdint.h> (included via "sha1.h" to define 32 and 8
19  *      bit unsigned integer types.  If your C compiler does not
20  *      support 32 bit unsigned integers, this code is not
21  *      appropriate.
22  *
23  *  Caveats:
24  *      SHA-1 is designed to work with messages less than 2^64 bits
25  *      long.  Although SHA-1 allows a message digest to be generated
26  *      for messages of any number of bits less than 2^64, this
27  *      implementation only works with messages with a length that is
28  *      a multiple of the size of an 8-bit character.
29  *
30  *  See sha1.h for copyright
31  */
32
33 #include "sha1.h"
34
35 /*
36  *  Define the SHA1 circular left shift macro
37  */
38 #define SHA1CircularShift(bits,word) \
39                 (((word) << (bits)) | ((word) >> (32-(bits))))
40
41 /* Local Function Prototyptes */
42 static void SHA1PadMessage(SHA1Context *);
43 static void SHA1ProcessMessageBlock(SHA1Context *);
44
45 /*
46  *  SHA1Init
47  *
48  *  Description:
49  *      This function will initialize the SHA1Context in preparation
50  *      for computing a new SHA1 message digest.
51  *
52  *  Parameters:
53  *      context: [in/out]
54  *          The context to reset.
55  *
56  *  Returns:
57  *      sha Error Code.
58  *
59  */
60 int SHA1Init(SHA1Context *context)
61 {
62     if (!context)
63     {
64         return shaNull;
65     }
66
67     context->Length_Low             = 0;
68     context->Length_High            = 0;
69     context->Message_Block_Index    = 0;
70
71     context->Intermediate_Hash[0]   = 0x67452301;
72     context->Intermediate_Hash[1]   = 0xEFCDAB89;
73     context->Intermediate_Hash[2]   = 0x98BADCFE;
74     context->Intermediate_Hash[3]   = 0x10325476;
75     context->Intermediate_Hash[4]   = 0xC3D2E1F0;
76
77     context->Computed   = 0;
78     context->Corrupted  = 0;
79
80     return shaSuccess;
81 }
82
83 /*
84  *  SHA1Final
85  *
86  *  Description:
87  *      This function will return the 160-bit message digest into the
88  *      Message_Digest array  provided by the caller.
89  *      NOTE: The first octet of hash is stored in the 0th element,
90  *            the last octet of hash in the 19th element.
91  *
92  *  Parameters:
93  *      context: [in/out]
94  *          The context to use to calculate the SHA-1 hash.
95  *      Message_Digest: [out]
96  *          Where the digest is returned.
97  *
98  *  Returns:
99  *      sha Error Code.
100  *
101  */
102 int SHA1Final(SHA1Context *context,
103               uint8_t Message_Digest[SHA1HashSize])
104 {
105     int i;
106
107     if (!context || !Message_Digest) {
108         return shaNull;
109     }
110
111     if (context->Corrupted) {
112         return context->Corrupted;
113     }
114
115     if (!context->Computed) {
116         SHA1PadMessage(context);
117         for(i=0; i<64; ++i) {
118             /* message may be sensitive, clear it out */
119             context->Message_Block[i] = 0;
120         }
121         context->Length_Low = 0;    /* and clear length */
122         context->Length_High = 0;
123         context->Computed = 1;
124
125     }
126
127     for(i = 0; i < SHA1HashSize; ++i) {
128         Message_Digest[i] = context->Intermediate_Hash[i>>2]
129                             >> 8 * ( 3 - ( i & 0x03 ) );
130     }
131
132     return shaSuccess;
133 }
134
135 /*
136  *  SHA1Update
137  *
138  *  Description:
139  *      This function accepts an array of octets as the next portion
140  *      of the message.
141  *
142  *  Parameters:
143  *      context: [in/out]
144  *          The SHA context to update
145  *      message_array: [in]
146  *          An array of characters representing the next portion of
147  *          the message.
148  *      length: [in]
149  *          The length of the message in message_array
150  *
151  *  Returns:
152  *      sha Error Code.
153  *
154  */
155 int SHA1Update(SHA1Context    *context,
156                const uint8_t  *message_array,
157                unsigned       length)
158 {
159     if (!length) {
160         return shaSuccess;
161     }
162
163     if (!context || !message_array) {
164         return shaNull;
165     }
166
167     if (context->Computed) {
168         context->Corrupted = shaStateError;
169
170         return shaStateError;
171     }
172
173     if (context->Corrupted) {
174          return context->Corrupted;
175     }
176     while(length-- && !context->Corrupted) {
177        context->Message_Block[context->Message_Block_Index++] =
178                     (*message_array & 0xFF);
179
180        context->Length_Low += 8;
181        if (context->Length_Low == 0) {
182            context->Length_High++;
183            if (context->Length_High == 0) {
184                /* Message is too long */
185                context->Corrupted = 1;
186            }
187        }
188
189        if (context->Message_Block_Index == 64) {
190            SHA1ProcessMessageBlock(context);
191        }
192
193        message_array++;
194     }
195
196     return shaSuccess;
197 }
198
199 /*
200  *  SHA1ProcessMessageBlock
201  *
202  *  Description:
203  *      This function will process the next 512 bits of the message
204  *      stored in the Message_Block array.
205  *
206  *  Parameters:
207  *      None.
208  *
209  *  Returns:
210  *      Nothing.
211  *
212  *  Comments:
213
214  *      Many of the variable names in this code, especially the
215  *      single character names, were used because those were the
216  *      names used in the publication.
217  *
218  *
219  */
220 static void SHA1ProcessMessageBlock(SHA1Context *context)
221 {
222     const uint32_t K[] =    {       /* Constants defined in SHA-1   */
223                             0x5A827999,
224                             0x6ED9EBA1,
225                             0x8F1BBCDC,
226                             0xCA62C1D6
227                             };
228     int           t;                 /* Loop counter                */
229     uint32_t      temp;              /* Temporary word value        */
230     uint32_t      W[80];             /* Word sequence               */
231     uint32_t      A, B, C, D, E;     /* Word buffers                */
232
233     /*
234      *  Initialize the first 16 words in the array W
235      */
236     for(t = 0; t < 16; t++) {
237         W[t] = context->Message_Block[t * 4] << 24;
238         W[t] |= context->Message_Block[t * 4 + 1] << 16;
239         W[t] |= context->Message_Block[t * 4 + 2] << 8;
240         W[t] |= context->Message_Block[t * 4 + 3];
241     }
242
243     for(t = 16; t < 80; t++) {
244        W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
245     }
246
247     A = context->Intermediate_Hash[0];
248     B = context->Intermediate_Hash[1];
249     C = context->Intermediate_Hash[2];
250     D = context->Intermediate_Hash[3];
251     E = context->Intermediate_Hash[4];
252
253     for(t = 0; t < 20; t++) {
254         temp =  SHA1CircularShift(5,A) +
255                 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
256         E = D;
257         D = C;
258         C = SHA1CircularShift(30,B);
259
260         B = A;
261         A = temp;
262     }
263
264     for(t = 20; t < 40; t++) {
265         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
266         E = D;
267         D = C;
268         C = SHA1CircularShift(30,B);
269         B = A;
270         A = temp;
271     }
272
273     for(t = 40; t < 60; t++) {
274         temp = SHA1CircularShift(5,A) +
275                ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
276         E = D;
277         D = C;
278         C = SHA1CircularShift(30,B);
279         B = A;
280         A = temp;
281     }
282
283     for(t = 60; t < 80; t++) {
284         temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
285         E = D;
286         D = C;
287         C = SHA1CircularShift(30,B);
288         B = A;
289         A = temp;
290     }
291
292     context->Intermediate_Hash[0] += A;
293     context->Intermediate_Hash[1] += B;
294     context->Intermediate_Hash[2] += C;
295     context->Intermediate_Hash[3] += D;
296     context->Intermediate_Hash[4] += E;
297
298     context->Message_Block_Index = 0;
299 }
300
301 /*
302  *  SHA1PadMessage
303  *
304
305  *  Description:
306  *      According to the standard, the message must be padded to an even
307  *      512 bits.  The first padding bit must be a '1'.  The last 64
308  *      bits represent the length of the original message.  All bits in
309  *      between should be 0.  This function will pad the message
310  *      according to those rules by filling the Message_Block array
311  *      accordingly.  It will also call the ProcessMessageBlock function
312  *      provided appropriately.  When it returns, it can be assumed that
313  *      the message digest has been computed.
314  *
315  *  Parameters:
316  *      context: [in/out]
317  *          The context to pad
318  *      ProcessMessageBlock: [in]
319  *          The appropriate SHA*ProcessMessageBlock function
320  *  Returns:
321  *      Nothing.
322  *
323  */
324
325 static void SHA1PadMessage(SHA1Context *context)
326 {
327     /*
328      *  Check to see if the current message block is too small to hold
329      *  the initial padding bits and length.  If so, we will pad the
330      *  block, process it, and then continue padding into a second
331      *  block.
332      */
333     if (context->Message_Block_Index > 55) {
334         context->Message_Block[context->Message_Block_Index++] = 0x80;
335         while(context->Message_Block_Index < 64) {
336             context->Message_Block[context->Message_Block_Index++] = 0;
337         }
338
339         SHA1ProcessMessageBlock(context);
340
341         while(context->Message_Block_Index < 56) {
342             context->Message_Block[context->Message_Block_Index++] = 0;
343         }
344     } else {
345         context->Message_Block[context->Message_Block_Index++] = 0x80;
346         while(context->Message_Block_Index < 56) {
347
348             context->Message_Block[context->Message_Block_Index++] = 0;
349         }
350     }
351
352     /*
353      *  Store the message length as the last 8 octets
354      */
355     context->Message_Block[56] = context->Length_High >> 24;
356     context->Message_Block[57] = context->Length_High >> 16;
357     context->Message_Block[58] = context->Length_High >> 8;
358     context->Message_Block[59] = context->Length_High;
359     context->Message_Block[60] = context->Length_Low >> 24;
360     context->Message_Block[61] = context->Length_Low >> 16;
361     context->Message_Block[62] = context->Length_Low >> 8;
362     context->Message_Block[63] = context->Length_Low;
363
364     SHA1ProcessMessageBlock(context);
365 }
366
367 #ifdef TEST_DRIVER
368
369 /*
370  *  sha1test.c
371  *
372  *  Description:
373  *      This file will exercise the SHA-1 code performing the three
374  *      tests documented in FIPS PUB 180-1 plus one which calls
375  *      SHA1Input with an exact multiple of 512 bits, plus a few
376  *      error test checks.
377  *
378  *  Portability Issues:
379  *      None.
380  *
381  */
382
383 #include <stdint.h>
384 #include <stdio.h>
385 #include <string.h>
386 #include "sha1.h"
387
388 /*
389  *  Define patterns for testing
390  */
391 #define TEST1   "abc"
392 #define TEST2a  "abcdbcdecdefdefgefghfghighijhi"
393
394 #define TEST2b  "jkijkljklmklmnlmnomnopnopq"
395 #define TEST2   TEST2a TEST2b
396 #define TEST3   "a"
397 #define TEST4a  "01234567012345670123456701234567"
398 #define TEST4b  "01234567012345670123456701234567"
399     /* an exact multiple of 512 bits */
400 #define TEST4   TEST4a TEST4b
401 char *testarray[4] =
402 {
403     TEST1,
404     TEST2,
405     TEST3,
406     TEST4
407 };
408 long int repeatcount[4] = { 1, 1, 1000000, 10 };
409 char *resultarray[4] =
410 {
411     "A9 99 3E 36 47 06 81 6A BA 3E 25 71 78 50 C2 6C 9C D0 D8 9D",
412     "84 98 3E 44 1C 3B D2 6E BA AE 4A A1 F9 51 29 E5 E5 46 70 F1",
413     "34 AA 97 3C D4 C4 DA A4 F6 1E EB 2B DB AD 27 31 65 34 01 6F",
414     "DE A3 56 A2 CD DD 90 C7 A7 EC ED C5 EB B5 63 93 4F 46 04 52"
415 };
416
417 int main()
418 {
419     SHA1Context sha;
420     int i, j, err;
421     uint8_t Message_Digest[20];
422
423     /*
424      *  Perform SHA-1 tests
425      */
426     for(j = 0; j < 4; ++j) {
427         printf( "\nTest %d: %d, '%s'\n",
428                 j+1,
429                 repeatcount[j],
430                 testarray[j]);
431
432         err = SHA1Init(&sha);
433         if (err) {
434             fprintf(stderr, "SHA1Reset Error %d.\n", err );
435             break;    /* out of for j loop */
436         }
437
438         for(i = 0; i < repeatcount[j]; ++i) {
439
440             err = SHA1Input(&sha,
441                   (const unsigned char *) testarray[j],
442                   strlen(testarray[j]));
443             if (err) {
444                 fprintf(stderr, "SHA1Input Error %d.\n", err );
445                 break;    /* out of for i loop */
446             }
447         }
448
449         err = SHA1Final(&sha, Message_Digest);
450         if (err) {
451             fprintf(stderr,
452             "SHA1Result Error %d, could not compute message digest.\n",
453             err );
454         }
455         else
456         {
457             printf("\t");
458             for(i = 0; i < 20 ; ++i) {
459                 printf("%02X ", Message_Digest[i]);
460             }
461             printf("\n");
462         }
463         printf("Should match:\n");
464         printf("\t%s\n", resultarray[j]);
465     }
466
467     /* Test some error returns */
468     err = SHA1Input(&sha,(const unsigned char *) testarray[1], 1);
469     printf ("\nError %d. Should be %d.\n", err, shaStateError );
470     err = SHA1Init(0);
471     printf ("\nError %d. Should be %d.\n", err, shaNull );
472     return 0;
473 }
474
475 #endif /* TEST_DRIVER */
476
477 #ifdef SHA1_SUM
478 /*
479  * Reads a single ASCII file and prints the HEX sha1 sum.
480  */
481 #include <stdio.h>
482 int main(int argc, char *argv[])
483 {
484    FILE *fd;
485    SHA1Context ctx;
486    char buf[5000];
487    char signature[25];
488
489    if (argc < 1) {
490       printf("Must have filename\n");
491       exit(1);
492    }
493    fd = fopen(argv[1], "r");
494    if (!fd) {
495       printf("Could not open %s: ERR=%s\n", argv[1], strerror(errno));
496       exit(1);
497    }
498    SHA1Init(&ctx);
499    while (fgets(buf, sizeof(buf), fd)) {
500       SHA1Update(&ctx, (unsigned char *)buf, strlen(buf));
501    }
502    SHA1Final(&ctx, (unsigned char *)signature);
503    for (int i=0; i < 20; i++) {
504       printf("%02x", signature[i]& 0xFF);
505    }
506    printf("  %s\n", argv[1]);
507 }
508 #endif