GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/sha1.c Lines: 0 117 0.0 %
Date: 2020-12-10 21:44:00 Branches: 0 40 0.0 %

Line Branch Exec Source
1
/*
2
 *  sha1.c
3
 *
4
 *  Copyright (C) 1998, 2009
5
 *  Paul E. Jones <paulej@packetizer.com>
6
 *  All Rights Reserved
7
 *
8
 * Freeware Public License (FPL)
9
 *
10
 * This software is licensed as "freeware."  Permission to distribute
11
 * this software in source and binary forms, including incorporation
12
 * into other products, is hereby granted without a fee.  THIS SOFTWARE
13
 * IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES,
14
 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
15
 * AND FITNESS FOR A PARTICULAR PURPOSE.  THE AUTHOR SHALL NOT BE HELD
16
 * LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER
17
 * DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA
18
 * OR DATA BEING RENDERED INACCURATE.
19
 *
20
 *****************************************************************************
21
 *  $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
22
 *****************************************************************************
23
 *
24
 *  Description:
25
 *      This file implements the Secure Hashing Standard as defined
26
 *      in FIPS PUB 180-1 published April 17, 1995.
27
 *
28
 *      The Secure Hashing Standard, which uses the Secure Hashing
29
 *      Algorithm (SHA), produces a 160-bit message digest for a
30
 *      given data stream.  In theory, it is highly improbable that
31
 *      two messages will produce the same message digest.  Therefore,
32
 *      this algorithm can serve as a means of providing a "fingerprint"
33
 *      for a message.
34
 *
35
 *  Portability Issues:
36
 *      SHA-1 is defined in terms of 32-bit "words".  This code was
37
 *      written with the expectation that the processor has at least
38
 *      a 32-bit machine word size.  If the machine word size is larger,
39
 *      the code should still function properly.  One caveat to that
40
 *      is that the input functions taking characters and character
41
 *      arrays assume that only 8 bits of information are stored in each
42
 *      character.
43
 *
44
 *  Caveats:
45
 *      SHA-1 is designed to work with messages less than 2^64 bits
46
 *      long. Although SHA-1 allows a message digest to be generated for
47
 *      messages of any number of bits less than 2^64, this
48
 *      implementation only works with messages with a length that is a
49
 *      multiple of the size of an 8-bit character.
50
 *
51
 */
52
53
#include "sha1.h"
54
55
/*
56
 *  Define the circular shift macro
57
 */
58
#define SHA1CircularShift(bits,word) \
59
                ((((word) << (bits)) & 0xFFFFFFFF) | \
60
                ((word) >> (32-(bits))))
61
62
/* Function prototypes */
63
void SHA1ProcessMessageBlock(SHA1Context *);
64
void SHA1PadMessage(SHA1Context *);
65
66
/*
67
 *  SHA1Reset
68
 *
69
 *  Description:
70
 *      This function will initialize the SHA1Context in preparation
71
 *      for computing a new message digest.
72
 *
73
 *  Parameters:
74
 *      context: [in/out]
75
 *          The context to reset.
76
 *
77
 *  Returns:
78
 *      Nothing.
79
 *
80
 *  Comments:
81
 *
82
 */
83
void SHA1Reset(SHA1Context *context)
84
{
85
    context->Length_Low             = 0;
86
    context->Length_High            = 0;
87
    context->Message_Block_Index    = 0;
88
89
    context->Message_Digest[0]      = 0x67452301;
90
    context->Message_Digest[1]      = 0xEFCDAB89;
91
    context->Message_Digest[2]      = 0x98BADCFE;
92
    context->Message_Digest[3]      = 0x10325476;
93
    context->Message_Digest[4]      = 0xC3D2E1F0;
94
95
    context->Computed   = 0;
96
    context->Corrupted  = 0;
97
}
98
99
/*
100
 *  SHA1Result
101
 *
102
 *  Description:
103
 *      This function will return the 160-bit message digest into the
104
 *      Message_Digest array within the SHA1Context provided
105
 *
106
 *  Parameters:
107
 *      context: [in/out]
108
 *          The context to use to calculate the SHA-1 hash.
109
 *
110
 *  Returns:
111
 *      1 if successful, 0 if it failed.
112
 *
113
 *  Comments:
114
 *
115
 */
116
int SHA1Result(SHA1Context *context)
117
{
118
119
    if (context->Corrupted)
120
    {
121
        return 0;
122
    }
123
124
    if (!context->Computed)
125
    {
126
        SHA1PadMessage(context);
127
        context->Computed = 1;
128
    }
129
130
    return 1;
131
}
132
133
/*
134
 *  SHA1Input
135
 *
136
 *  Description:
137
 *      This function accepts an array of octets as the next portion of
138
 *      the message.
139
 *
140
 *  Parameters:
141
 *      context: [in/out]
142
 *          The SHA-1 context to update
143
 *      message_array: [in]
144
 *          An array of characters representing the next portion of the
145
 *          message.
146
 *      length: [in]
147
 *          The length of the message in message_array
148
 *
149
 *  Returns:
150
 *      Nothing.
151
 *
152
 *  Comments:
153
 *
154
 */
155
void SHA1Input(     SHA1Context         *context,
156
                    const unsigned char *message_array,
157
                    unsigned            length)
158
{
159
    if (!length)
160
    {
161
        return;
162
    }
163
164
    if (context->Computed || context->Corrupted)
165
    {
166
        context->Corrupted = 1;
167
        return;
168
    }
169
170
    while(length-- && !context->Corrupted)
171
    {
172
        context->Message_Block[context->Message_Block_Index++] =
173
                                                (*message_array & 0xFF);
174
175
        context->Length_Low += 8;
176
        /* Force it to 32 bits */
177
        context->Length_Low &= 0xFFFFFFFF;
178
        if (context->Length_Low == 0)
179
        {
180
            context->Length_High++;
181
            /* Force it to 32 bits */
182
            context->Length_High &= 0xFFFFFFFF;
183
            if (context->Length_High == 0)
184
            {
185
                /* Message is too long */
186
                context->Corrupted = 1;
187
            }
188
        }
189
190
        if (context->Message_Block_Index == 64)
191
        {
192
            SHA1ProcessMessageBlock(context);
193
        }
194
195
        message_array++;
196
    }
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
 *      Many of the variable names in the SHAContext, especially the
214
 *      single character names, were used because those were the names
215
 *      used in the publication.
216
 *
217
 *
218
 */
219
void SHA1ProcessMessageBlock(SHA1Context *context)
220
{
221
    const unsigned K[] =            /* Constants defined in SHA-1   */
222
    {
223
        0x5A827999,
224
        0x6ED9EBA1,
225
        0x8F1BBCDC,
226
        0xCA62C1D6
227
    };
228
    int         t;                  /* Loop counter                 */
229
    unsigned    temp;               /* Temporary word value         */
230
    unsigned    W[80];              /* Word sequence                */
231
    unsigned    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
    {
238
        W[t] = ((unsigned) context->Message_Block[t * 4]) << 24;
239
        W[t] |= ((unsigned) context->Message_Block[t * 4 + 1]) << 16;
240
        W[t] |= ((unsigned) context->Message_Block[t * 4 + 2]) << 8;
241
        W[t] |= ((unsigned) context->Message_Block[t * 4 + 3]);
242
    }
243
244
    for(t = 16; t < 80; t++)
245
    {
246
       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
247
    }
248
249
    A = context->Message_Digest[0];
250
    B = context->Message_Digest[1];
251
    C = context->Message_Digest[2];
252
    D = context->Message_Digest[3];
253
    E = context->Message_Digest[4];
254
255
    for(t = 0; t < 20; t++)
256
    {
257
        temp =  SHA1CircularShift(5,A) +
258
                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
259
        temp &= 0xFFFFFFFF;
260
        E = D;
261
        D = C;
262
        C = SHA1CircularShift(30,B);
263
        B = A;
264
        A = temp;
265
    }
266
267
    for(t = 20; t < 40; t++)
268
    {
269
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
270
        temp &= 0xFFFFFFFF;
271
        E = D;
272
        D = C;
273
        C = SHA1CircularShift(30,B);
274
        B = A;
275
        A = temp;
276
    }
277
278
    for(t = 40; t < 60; t++)
279
    {
280
        temp = SHA1CircularShift(5,A) +
281
               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
282
        temp &= 0xFFFFFFFF;
283
        E = D;
284
        D = C;
285
        C = SHA1CircularShift(30,B);
286
        B = A;
287
        A = temp;
288
    }
289
290
    for(t = 60; t < 80; t++)
291
    {
292
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
293
        temp &= 0xFFFFFFFF;
294
        E = D;
295
        D = C;
296
        C = SHA1CircularShift(30,B);
297
        B = A;
298
        A = temp;
299
    }
300
301
    context->Message_Digest[0] =
302
                        (context->Message_Digest[0] + A) & 0xFFFFFFFF;
303
    context->Message_Digest[1] =
304
                        (context->Message_Digest[1] + B) & 0xFFFFFFFF;
305
    context->Message_Digest[2] =
306
                        (context->Message_Digest[2] + C) & 0xFFFFFFFF;
307
    context->Message_Digest[3] =
308
                        (context->Message_Digest[3] + D) & 0xFFFFFFFF;
309
    context->Message_Digest[4] =
310
                        (context->Message_Digest[4] + E) & 0xFFFFFFFF;
311
312
    context->Message_Block_Index = 0;
313
}
314
315
/*
316
 *  SHA1PadMessage
317
 *
318
 *  Description:
319
 *      According to the standard, the message must be padded to an even
320
 *      512 bits.  The first padding bit must be a '1'.  The last 64
321
 *      bits represent the length of the original message.  All bits in
322
 *      between should be 0.  This function will pad the message
323
 *      according to those rules by filling the Message_Block array
324
 *      accordingly.  It will also call SHA1ProcessMessageBlock()
325
 *      appropriately.  When it returns, it can be assumed that the
326
 *      message digest has been computed.
327
 *
328
 *  Parameters:
329
 *      context: [in/out]
330
 *          The context to pad
331
 *
332
 *  Returns:
333
 *      Nothing.
334
 *
335
 *  Comments:
336
 *
337
 */
338
void SHA1PadMessage(SHA1Context *context)
339
{
340
    /*
341
     *  Check to see if the current message block is too small to hold
342
     *  the initial padding bits and length.  If so, we will pad the
343
     *  block, process it, and then continue padding into a second
344
     *  block.
345
     */
346
    if (context->Message_Block_Index > 55)
347
    {
348
        context->Message_Block[context->Message_Block_Index++] = 0x80;
349
        while(context->Message_Block_Index < 64)
350
        {
351
            context->Message_Block[context->Message_Block_Index++] = 0;
352
        }
353
354
        SHA1ProcessMessageBlock(context);
355
356
        while(context->Message_Block_Index < 56)
357
        {
358
            context->Message_Block[context->Message_Block_Index++] = 0;
359
        }
360
    }
361
    else
362
    {
363
        context->Message_Block[context->Message_Block_Index++] = 0x80;
364
        while(context->Message_Block_Index < 56)
365
        {
366
            context->Message_Block[context->Message_Block_Index++] = 0;
367
        }
368
    }
369
370
    /*
371
     *  Store the message length as the last 8 octets
372
     */
373
    context->Message_Block[56] = (context->Length_High >> 24) & 0xFF;
374
    context->Message_Block[57] = (context->Length_High >> 16) & 0xFF;
375
    context->Message_Block[58] = (context->Length_High >> 8) & 0xFF;
376
    context->Message_Block[59] = (context->Length_High) & 0xFF;
377
    context->Message_Block[60] = (context->Length_Low >> 24) & 0xFF;
378
    context->Message_Block[61] = (context->Length_Low >> 16) & 0xFF;
379
    context->Message_Block[62] = (context->Length_Low >> 8) & 0xFF;
380
    context->Message_Block[63] = (context->Length_Low) & 0xFF;
381
382
    SHA1ProcessMessageBlock(context);
383
}