Diff

Differences From Artifact [a03e9d2d38]:

To Artifact [e3f79ad8a1]:


1
2
3







4
5
6






7




8

9
10
11
12
13

14
15
16
17
18
19
20



21
22
23
24
25

26
27
28
29



30
31

32

33
34
35
36
37

38
39












40

41
42



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60
61
62


63
64
65
66
67
68


69

70
71
72
73
74





75
76
77


78
79

80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149



150
151
152

153
154
155
156
157
158
159


160
161
162

163
164

165
166
167
168
169

170
171
172

173
174
175
176
177
178
179
180


181
182
183

184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199


200
201

202
203
204
205

206
























































































207

208
209
210
211

212
213
214
215



216
217
218



219
220
221


222
223
224
225
226




227
228
229
230
231

232
233


234
235
236
237
238
239
240
241






242
243
244
245
246




247
248
249
250
251
252





253
254

255
256

257
258
259
260
261
262
263





264
265

266
267
268
269
270
271
272
273
274







275
276

277
278
279
280
281
282
283
284







285
286

287
288
289
290
291
292
293
294
295







296
297

298
299
300
301
302
303
304
305







306
307
308
309
310
311





312
313

314
315


316





























317
318

319
320
321
322
323
324
325






326
327
328


329
330
331
332
333
334
335
336











337
338
339
340

341
342
343
344
345
346
347
348







349
350

351
352
353
354
355
356
357
358

359
360
361


362
363


364
365

366
367
368
369




370
371
372
373
374
375
376
377
378
379
380
381
382











383
384

385




1
2
3
4
5
6
7
8


9
10
11
12
13
14
15
16
17
18
19

20





21
22
23
24
25



26
27
28
29
30
31
32

33




34
35
36
37
38
39

40
41
42
43
44

45
46
47
48
49
50
51
52
53
54
55
56
57
58
59

60


61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79

80
81


82
83






84
85
86
87





88
89
90
91
92
93


94
95
96

97
























































98
99
100
101
102
103
104
105
106
107
108



109
110
111
112
113

114
115
116
117
118
119


120
121

122

123


124





125



126








127
128



129

130

131
132












133
134


135

136
137

138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227

228
229
230
231

232
233



234
235
236
237


238
239
240
241


242
243
244




245
246
247
248


249
250
251
252


253
254








255
256
257
258
259
260
261




262
263
264
265






266
267
268
269
270
271

272


273

274





275
276
277
278
279
280

281









282
283
284
285
286
287
288
289

290








291
292
293
294
295
296
297
298

299









300
301
302
303
304
305
306
307

308








309
310
311
312
313
314
315
316





317
318
319
320
321


322
323
324
325
326

327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356

357
358






359
360
361
362
363
364



365
366
367







368
369
370
371
372
373
374
375
376
377
378

379


380
381







382
383
384
385
386
387
388


389








390



391
392


393
394


395




396
397
398
399













400
401
402
403
404
405
406
407
408
409
410
411

412
413
414
-
-
-
+
+
+
+
+
+
+

-
-
+
+
+
+
+
+

+
+
+
+
-
+
-
-
-
-
-
+




-
-
-
+
+
+




-
+
-
-
-
-
+
+
+


+
-
+




-
+


+
+
+
+
+
+
+
+
+
+
+
+
-
+
-
-
+
+
+
















-
+

-
-
+
+
-
-
-
-
-
-
+
+

+
-
-
-
-
-
+
+
+
+
+

-
-
+
+

-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-











-
-
-
+
+
+


-
+





-
-
+
+
-

-
+
-
-
+
-
-
-
-
-
+
-
-
-
+
-
-
-
-
-
-
-
-
+
+
-
-
-
+
-

-
+

-
-
-
-
-
-
-
-
-
-
-
-
+
+
-
-
+
-


-
+

+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+



-
+

-
-
-
+
+
+

-
-
+
+
+

-
-
+
+

-
-
-
-
+
+
+
+
-
-



+
-
-
+
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+

-
-
-
-
+
+
+
+
-
-
-
-
-
-
+
+
+
+
+

-
+
-
-
+
-

-
-
-
-
-
+
+
+
+
+

-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
+
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
+
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+

-
-
-
-
-
+
+
+
+
+
-
-
+


+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+

-
+

-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
+
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
-

-
-
+

-
-
-
-
-
-
-
+
+
+
+
+
+
+
-
-
+
-
-
-
-
-
-
-
-
+
-
-
-
+
+
-
-
+
+
-
-
+
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+

-
+

+
/*
 *  sha1.c
 *
/**************************** sha1.c ***************************/
/***************** See RFC 6234 for details. *******************/
/* Copyright (c) 2011 IETF Trust and the persons identified as */
/* authors of the code.  All rights reserved.                  */
/* See sha.h for terms of use and redistribution.              */

/*
 *  Description:
 *      This file implements the Secure Hashing Algorithm 1 as
 *      defined in FIPS PUB 180-1 published April 17, 1995.
 *      This file implements the Secure Hash Algorithm SHA-1
 *      as defined in the U.S. National Institute of Standards
 *      and Technology Federal Information Processing Standards
 *      Publication (FIPS PUB) 180-3 published in October 2008
 *      and formerly defined in its predecessors, FIPS PUB 180-1
 *      and FIP PUB 180-2.
 *
 *      A combined document showing all algorithms is available at
 *              http://csrc.nist.gov/publications/fips/
 *                     fips180-3/fips180-3_final.pdf
 *
 *      The SHA-1, produces a 160-bit message digest for a given
 *      The SHA-1 algorithm produces a 160-bit message digest for a
 *      data stream.  It should take about 2**n steps to find a
 *      message with the same digest as a given message and
 *      2**(n/2) to find any two messages with the same digest,
 *      when n is the digest size in bits.  Therefore, this
 *      algorithm can serve as a means of providing a
 *      given data stream that can serve as a means of providing a
 *      "fingerprint" for a message.
 *
 *  Portability Issues:
 *      SHA-1 is defined in terms of 32-bit "words".  This code
 *      uses <stdint.h> (included via "sha1.h" to define 32 and 8
 *      bit unsigned integer types.  If your C compiler does not
 *      support 32 bit unsigned integers, this code is not
 *      uses <stdint.h> (included via "sha.h") to define 32- and
 *      8-bit unsigned integer types.  If your C compiler does
 *      not support 32-bit unsigned integers, this code is not
 *      appropriate.
 *
 *  Caveats:
 *      SHA-1 is designed to work with messages less than 2^64 bits
 *      long.  Although SHA-1 allows a message digest to be generated
 *      long.  This implementation uses SHA1Input() to hash the bits
 *      for messages of any number of bits less than 2^64, this
 *      implementation only works with messages with a length that is
 *      a multiple of the size of an 8-bit character.
 *
 *      that are a multiple of the size of an 8-bit octet, and then
 *      optionally uses SHA1FinalBits() to hash the final few bits of
 *      the input.
 */

#include "sha.h"
#include "sha1.h"
#include "sha-private.h"

/*
 *  Define the SHA1 circular left shift macro
 */
#define SHA1CircularShift(bits,word) \
#define SHA1_ROTL(bits,word) \
                (((word) << (bits)) | ((word) >> (32-(bits))))

/*
 * Add "length" to the length.
 * Set Corrupted when overflow has occurred.
 */
static uint32_t addTemp;
#define SHA1AddLength(context, length)                     \
    (addTemp = (context)->Length_Low,                      \
     (context)->Corrupted =                                \
        (((context)->Length_Low += (length)) < addTemp) && \
        (++(context)->Length_High == 0) ? shaInputTooLong  \
                                        : (context)->Corrupted )

/* Local Function Prototyptes */
/* Local Function Prototypes */
static void SHA1PadMessage(SHA1Context *);
static void SHA1ProcessMessageBlock(SHA1Context *);
static void SHA1ProcessMessageBlock(SHA1Context *context);
static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte);
static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte);

/*
 *  SHA1Reset
 *
 *  Description:
 *      This function will initialize the SHA1Context in preparation
 *      for computing a new SHA1 message digest.
 *
 *  Parameters:
 *      context: [in/out]
 *          The context to reset.
 *
 *  Returns:
 *      sha Error Code.
 *
 */
static int SHA1Reset(SHA1Context *context)
int SHA1Reset(SHA1Context *context)
{
    if (!context)
    {
  if (!context) return shaNull;

        return shaNull;
    }

    context->Length_Low             = 0;
    context->Length_High            = 0;
    context->Message_Block_Index    = 0;
  context->Length_High = context->Length_Low = 0;
  context->Message_Block_Index = 0;

  /* Initial Hash Values: FIPS 180-3 section 5.3.1 */
    context->Intermediate_Hash[0]   = 0x67452301;
    context->Intermediate_Hash[1]   = 0xEFCDAB89;
    context->Intermediate_Hash[2]   = 0x98BADCFE;
    context->Intermediate_Hash[3]   = 0x10325476;
    context->Intermediate_Hash[4]   = 0xC3D2E1F0;
  context->Intermediate_Hash[0]   = 0x67452301;
  context->Intermediate_Hash[1]   = 0xEFCDAB89;
  context->Intermediate_Hash[2]   = 0x98BADCFE;
  context->Intermediate_Hash[3]   = 0x10325476;
  context->Intermediate_Hash[4]   = 0xC3D2E1F0;

    context->Computed   = 0;
    context->Corrupted  = 0;
  context->Computed   = 0;
  context->Corrupted  = shaSuccess;

    return shaSuccess;
  return shaSuccess;
}

/*
 *  SHA1Result
 *
 *  Description:
 *      This function will return the 160-bit message digest into the
 *      Message_Digest array  provided by the caller.
 *      NOTE: The first octet of hash is stored in the 0th element,
 *            the last octet of hash in the 19th element.
 *
 *  Parameters:
 *      context: [in/out]
 *          The context to use to calculate the SHA-1 hash.
 *      Message_Digest: [out]
 *          Where the digest is returned.
 *
 *  Returns:
 *      sha Error Code.
 *
 */
static int SHA1Result( SHA1Context *context,
                uint8_t Message_Digest[SHA1HashSize])
{
    int i;

    if (!context || !Message_Digest)
    {
        return shaNull;
    }

    if (context->Corrupted)
    {
        return context->Corrupted;
    }

    if (!context->Computed)
    {
        SHA1PadMessage(context);
        for(i=0; i<64; ++i)
        {
            /* message may be sensitive, clear it out */
            context->Message_Block[i] = 0;
        }
        context->Length_Low = 0;    /* and clear length */
        context->Length_High = 0;
        context->Computed = 1;
    }

    for(i = 0; i < SHA1HashSize; ++i)
    {
        Message_Digest[i] = context->Intermediate_Hash[i>>2]
                            >> 8 * ( 3 - ( i & 0x03 ) );
    }

    return shaSuccess;
}

/*
 *  SHA1Input
 *
 *  Description:
 *      This function accepts an array of octets as the next portion
 *      of the message.
 *
 *  Parameters:
 *      context: [in/out]
 *          The SHA context to update
 *      message_array: [in]
 *          An array of characters representing the next portion of
 *          The SHA context to update.
 *      message_array[ ]: [in]
 *          An array of octets representing the next portion of
 *          the message.
 *      length: [in]
 *          The length of the message in message_array
 *          The length of the message in message_array.
 *
 *  Returns:
 *      sha Error Code.
 *
 */
static int SHA1Input(    SHA1Context    *context,
                  const uint8_t  *message_array,
int SHA1Input(SHA1Context *context,
    const uint8_t *message_array, unsigned length)
                  unsigned       length)
{
    if (!length)
  if (!context) return shaNull;
    {
        return shaSuccess;
  if (!length) return shaSuccess;
    }

    if (!context || !message_array)
    {
        return shaNull;
  if (!message_array) return shaNull;
    }

    if (context->Computed)
  if (context->Computed) return context->Corrupted = shaStateError;
    {
        context->Corrupted = shaStateError;

        return shaStateError;
    }

    if (context->Corrupted)
    {
  if (context->Corrupted) return context->Corrupted;

         return context->Corrupted;
    }
    while(length-- && !context->Corrupted)
  while (length--) {
    {
    context->Message_Block[context->Message_Block_Index++] =
                    (*message_array & 0xFF);
      *message_array;

    context->Length_Low += 8;
    if (context->Length_Low == 0)
    {
        context->Length_High++;
        if (context->Length_High == 0)
        {
            /* Message is too long */
            context->Corrupted = 1;
        }
    }

    if (context->Message_Block_Index == 64)
    if ((SHA1AddLength(context, 8) == shaSuccess) &&
      (context->Message_Block_Index == SHA1_Message_Block_Size))
    {
        SHA1ProcessMessageBlock(context);
      SHA1ProcessMessageBlock(context);
    }

    message_array++;
    }
  }

  return context->Corrupted;
}

/*
 * SHA1FinalBits
 *
 * Description:
 *   This function will add in any final bits of the message.
 *
 * Parameters:
 *   context: [in/out]
 *     The SHA context to update.
 *   message_bits: [in]
 *     The final bits of the message, in the upper portion of the
 *     byte.  (Use 0b###00000 instead of 0b00000### to input the
 *     three bits ###.)
 *   length: [in]
 *     The number of bits in message_bits, between 1 and 7.
 *
 * Returns:
 *   sha Error Code.
 */
int SHA1FinalBits(SHA1Context *context, uint8_t message_bits,
    unsigned int length)
{
  static uint8_t masks[8] = {
      /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
      /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
      /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
      /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
  };

  static uint8_t markbit[8] = {
      /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
      /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
      /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
      /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
  };

  if (!context) return shaNull;
  if (!length) return shaSuccess;
  if (context->Corrupted) return context->Corrupted;
  if (context->Computed) return context->Corrupted = shaStateError;
  if (length >= 8) return context->Corrupted = shaBadParam;

  SHA1AddLength(context, length);
  SHA1Finalize(context,
    (uint8_t) ((message_bits & masks[length]) | markbit[length]));

  return context->Corrupted;
}

/*
 * SHA1Result
 *
 * Description:
 *   This function will return the 160-bit message digest
 *   into the Message_Digest array provided by the caller.
 *   NOTE:
 *    The first octet of hash is stored in the element with index 0,
 *      the last octet of hash in the element with index 19.
 *
 * Parameters:
 *   context: [in/out]
 *     The context to use to calculate the SHA-1 hash.
 *   Message_Digest[ ]: [out]
 *     Where the digest is returned.
 *
 * Returns:
 *   sha Error Code.
 *
 */
int SHA1Result(SHA1Context *context,
    uint8_t Message_Digest[SHA1HashSize])
{
  int i;

  if (!context) return shaNull;
  if (!Message_Digest) return shaNull;
  if (context->Corrupted) return context->Corrupted;

  if (!context->Computed)
    SHA1Finalize(context, 0x80);

  for (i = 0; i < SHA1HashSize; ++i)
    Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i>>2]
                                   >> (8 * ( 3 - ( i & 0x03 ) )));

    return shaSuccess;
  return shaSuccess;
}

/*
 *  SHA1ProcessMessageBlock
 * SHA1ProcessMessageBlock
 *
 *  Description:
 *      This function will process the next 512 bits of the message
 *      stored in the Message_Block array.
 * Description:
 *   This helper function will process the next 512 bits of the
 *   message stored in the Message_Block array.
 *
 *  Parameters:
 *      None.
 * Parameters:
 *   context: [in/out]
 *     The SHA context to update.
 *
 *  Returns:
 *      Nothing.
 * Returns:
 *   Nothing.
 *
 *  Comments:
 *      Many of the variable names in this code, especially the
 *      single character names, were used because those were the
 *      names used in the publication.
 * Comments:
 *   Many of the variable names in this code, especially the
 *   single character names, were used because those were the
 *   names used in the Secure Hash Standard.
 *
 *
 */
static void SHA1ProcessMessageBlock(SHA1Context *context)
{
  /* Constants defined in FIPS 180-3, section 4.2.1 */
    const uint32_t K[] =    {       /* Constants defined in SHA-1   */
                            0x5A827999,
  const uint32_t K[4] = {
      0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
                            0x6ED9EBA1,
                            0x8F1BBCDC,
                            0xCA62C1D6
                            };
    int           t;                 /* Loop counter                */
    uint32_t      temp;              /* Temporary word value        */
    uint32_t      W[80];             /* Word sequence               */
    uint32_t      A, B, C, D, E;     /* Word buffers                */
  };

  int        t;               /* Loop counter */
  uint32_t   temp;            /* Temporary word value */
  uint32_t   W[80];           /* Word sequence */
  uint32_t   A, B, C, D, E;   /* Word buffers */

    /*
     *  Initialize the first 16 words in the array W
     */
    for(t = 0; t < 16; t++)
  /*
   * Initialize the first 16 words in the array W
   */
  for (t = 0; t < 16; t++) {
    {
        W[t] = context->Message_Block[t * 4] << 24;
        W[t] |= context->Message_Block[t * 4 + 1] << 16;
        W[t] |= context->Message_Block[t * 4 + 2] << 8;
        W[t] |= context->Message_Block[t * 4 + 3];
    }
    W[t]  = ((uint32_t)context->Message_Block[t * 4]) << 24;
    W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16;
    W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8;
    W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]);
  }

    for(t = 16; t < 80; t++)
  for (t = 16; t < 80; t++)
    {
       W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    W[t] = SHA1_ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
    }

    A = context->Intermediate_Hash[0];
    B = context->Intermediate_Hash[1];
    C = context->Intermediate_Hash[2];
    D = context->Intermediate_Hash[3];
    E = context->Intermediate_Hash[4];
  A = context->Intermediate_Hash[0];
  B = context->Intermediate_Hash[1];
  C = context->Intermediate_Hash[2];
  D = context->Intermediate_Hash[3];
  E = context->Intermediate_Hash[4];

    for(t = 0; t < 20; t++)
  for (t = 0; t < 20; t++) {
    {
        temp =  SHA1CircularShift(5,A) +
                ((B & C) | ((~B) & D)) + E + W[t] + K[0];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }
    temp = SHA1_ROTL(5,A) + SHA_Ch(B, C, D) + E + W[t] + K[0];
    E = D;
    D = C;
    C = SHA1_ROTL(30,B);
    B = A;
    A = temp;
  }

    for(t = 20; t < 40; t++)
  for (t = 20; t < 40; t++) {
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }
    temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[1];
    E = D;
    D = C;
    C = SHA1_ROTL(30,B);
    B = A;
    A = temp;
  }

    for(t = 40; t < 60; t++)
  for (t = 40; t < 60; t++) {
    {
        temp = SHA1CircularShift(5,A) +
               ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }
    temp = SHA1_ROTL(5,A) + SHA_Maj(B, C, D) + E + W[t] + K[2];
    E = D;
    D = C;
    C = SHA1_ROTL(30,B);
    B = A;
    A = temp;
  }

    for(t = 60; t < 80; t++)
  for (t = 60; t < 80; t++) {
    {
        temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
        E = D;
        D = C;
        C = SHA1CircularShift(30,B);
        B = A;
        A = temp;
    }
    temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[3];
    E = D;
    D = C;
    C = SHA1_ROTL(30,B);
    B = A;
    A = temp;
  }

    context->Intermediate_Hash[0] += A;
    context->Intermediate_Hash[1] += B;
    context->Intermediate_Hash[2] += C;
    context->Intermediate_Hash[3] += D;
    context->Intermediate_Hash[4] += E;
  context->Intermediate_Hash[0] += A;
  context->Intermediate_Hash[1] += B;
  context->Intermediate_Hash[2] += C;
  context->Intermediate_Hash[3] += D;
  context->Intermediate_Hash[4] += E;

    context->Message_Block_Index = 0;
  context->Message_Block_Index = 0;
}

/*
 * SHA1Finalize

 *
 * Description:
 *   This helper function finishes off the digest calculations.
 *
 * Parameters:
 *   context: [in/out]
 *     The SHA context to update.
 *   Pad_Byte: [in]
 *     The last byte to add to the message block before the 0-padding
 *     and length.  This will contain the last bits of the message
 *     followed by another single bit.  If the message was an
 *     exact multiple of 8-bits long, Pad_Byte will be 0x80.
 *
 * Returns:
 *   sha Error Code.
 *
 */
static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
{
  int i;
  SHA1PadMessage(context, Pad_Byte);
  /* message may be sensitive, clear it out */
  for (i = 0; i < SHA1_Message_Block_Size; ++i)
    context->Message_Block[i] = 0;
  context->Length_High = 0;     /* and clear length */
  context->Length_Low = 0;
  context->Computed = 1;
}

/*
 *  SHA1PadMessage
 * SHA1PadMessage
 *
 *  Description:
 *      According to the standard, the message must be padded to an even
 *      512 bits.  The first padding bit must be a '1'.  The last 64
 *      bits represent the length of the original message.  All bits in
 *      between should be 0.  This function will pad the message
 *      according to those rules by filling the Message_Block array
 * Description:
 *   According to the standard, the message must be padded to the next
 *   even multiple of 512 bits.  The first padding bit must be a '1'.
 *   The last 64 bits represent the length of the original message.
 *   All bits in between should be 0.  This helper function will pad
 *   the message according to those rules by filling the Message_Block
 *      accordingly.  It will also call the ProcessMessageBlock function
 *      provided appropriately.  When it returns, it can be assumed that
 *      the message digest has been computed.
 *   array accordingly.  When it returns, it can be assumed that the
 *   message digest has been computed.
 *
 *  Parameters:
 *      context: [in/out]
 *          The context to pad
 *      ProcessMessageBlock: [in]
 *          The appropriate SHA*ProcessMessageBlock function
 *  Returns:
 *      Nothing.
 * Parameters:
 *   context: [in/out]
 *     The context to pad.
 *   Pad_Byte: [in]
 *     The last byte to add to the message block before the 0-padding
 *     and length.  This will contain the last bits of the message
 *     followed by another single bit.  If the message was an
 *     exact multiple of 8-bits long, Pad_Byte will be 0x80.
 *
 * Returns:
 *   Nothing.
 *
 */

static void SHA1PadMessage(SHA1Context *context)
static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
{
    /*
     *  Check to see if the current message block is too small to hold
     *  the initial padding bits and length.  If so, we will pad the
     *  block, process it, and then continue padding into a second
     *  block.
     */
    if (context->Message_Block_Index > 55)
  /*
   * Check to see if the current message block is too small to hold
   * the initial padding bits and length.  If so, we will pad the
   * block, process it, and then continue padding into a second
   * block.
   */
  if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) {
    {
        context->Message_Block[context->Message_Block_Index++] = 0x80;
    context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
        while(context->Message_Block_Index < 64)
        {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }

        SHA1ProcessMessageBlock(context);

        while(context->Message_Block_Index < 56)
    while (context->Message_Block_Index < SHA1_Message_Block_Size)
        {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }
      context->Message_Block[context->Message_Block_Index++] = 0;

    }
    else
    SHA1ProcessMessageBlock(context);
  } else
    {
        context->Message_Block[context->Message_Block_Index++] = 0x80;
    context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
        while(context->Message_Block_Index < 56)
        {
            context->Message_Block[context->Message_Block_Index++] = 0;
        }

  while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8))
    context->Message_Block[context->Message_Block_Index++] = 0;

    }

    /*
     *  Store the message length as the last 8 octets
     */
    context->Message_Block[56] = context->Length_High >> 24;
    context->Message_Block[57] = context->Length_High >> 16;
    context->Message_Block[58] = context->Length_High >> 8;
    context->Message_Block[59] = context->Length_High;
    context->Message_Block[60] = context->Length_Low >> 24;
    context->Message_Block[61] = context->Length_Low >> 16;
    context->Message_Block[62] = context->Length_Low >> 8;
    context->Message_Block[63] = context->Length_Low;
  /*
   * Store the message length as the last 8 octets
   */
  context->Message_Block[56] = (uint8_t) (context->Length_High >> 24);
  context->Message_Block[57] = (uint8_t) (context->Length_High >> 16);
  context->Message_Block[58] = (uint8_t) (context->Length_High >> 8);
  context->Message_Block[59] = (uint8_t) (context->Length_High);
  context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24);
  context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16);
  context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8);
  context->Message_Block[63] = (uint8_t) (context->Length_Low);

    SHA1ProcessMessageBlock(context);
  SHA1ProcessMessageBlock(context);
}