sha1.cpp
Go to the documentation of this file.
1 /*
2  * sha1.cpp
3  *
4  * Copyright (C) 1998, 2009
5  * Paul E. Jones <paulej@packetizer.com>
6  * All Rights Reserved.
7  *
8  *****************************************************************************
9  * $Id: sha1.cpp 12 2009-06-22 19:34:25Z paulej $
10  *****************************************************************************
11  *
12  * Description:
13  * This class implements the Secure Hashing Standard as defined
14  * in FIPS PUB 180-1 published April 17, 1995.
15  *
16  * The Secure Hashing Standard, which uses the Secure Hashing
17  * Algorithm (SHA), produces a 160-bit message digest for a
18  * given data stream. In theory, it is highly improbable that
19  * two messages will produce the same message digest. Therefore,
20  * this algorithm can serve as a means of providing a "fingerprint"
21  * for a message.
22  *
23  * Portability Issues:
24  * SHA-1 is defined in terms of 32-bit "words". This code was
25  * written with the expectation that the processor has at least
26  * a 32-bit machine word size. If the machine word size is larger,
27  * the code should still function properly. One caveat to that
28  * is that the input functions taking characters and character arrays
29  * assume that only 8 bits of information are stored in each character.
30  *
31  * Caveats:
32  * SHA-1 is designed to work with messages less than 2^64 bits long.
33  * Although SHA-1 allows a message digest to be generated for
34  * messages of any number of bits less than 2^64, this implementation
35  * only works with messages with a length that is a multiple of 8
36  * bits.
37  *
38  */
39 
40 #include "sha1.h"
41 
42 namespace fhicl {
43 
44  /*
45  * SHA1
46  *
47  * Description:
48  * This is the constructor for the sha1 class.
49  *
50  * Parameters:
51  * None.
52  *
53  * Returns:
54  * Nothing.
55  *
56  * Comments:
57  *
58  */
59  SHA1::SHA1() { Reset(); }
60 
61  /*
62  * Reset
63  *
64  * Description:
65  * This function will initialize the sha1 class member variables
66  * in preparation for computing a new message digest.
67  *
68  * Parameters:
69  * None.
70  *
71  * Returns:
72  * Nothing.
73  *
74  * Comments:
75  *
76  */
77  void
79  {
80  Length_Low = 0;
81  Length_High = 0;
83 
84  H[0] = 0x67452301;
85  H[1] = 0xEFCDAB89;
86  H[2] = 0x98BADCFE;
87  H[3] = 0x10325476;
88  H[4] = 0xC3D2E1F0;
89 
90  Computed = false;
91  Corrupted = false;
92  }
93 
94  /*
95  * Result
96  *
97  * Description:
98  * This function will return the 160-bit message digest into the
99  * array provided.
100  *
101  * Parameters:
102  * message_digest_array: [out]
103  * This is an array of five unsigned integers which will be filled
104  * with the message digest that has been computed.
105  *
106  * Returns:
107  * True if successful, false if it failed.
108  *
109  * Comments:
110  *
111  */
112  bool
113  SHA1::Result(unsigned* message_digest_array)
114  {
115  int i; // Counter
116 
117  if (Corrupted) {
118  return false;
119  }
120 
121  if (!Computed) {
122  PadMessage();
123  Computed = true;
124  }
125 
126  for (i = 0; i < 5; i++) {
127  message_digest_array[i] = H[i];
128  }
129 
130  return true;
131  }
132 
133  /*
134  * Input
135  *
136  * Description:
137  * This function accepts an array of octets as the next portion of
138  * the message.
139  *
140  * Parameters:
141  * message_array: [in]
142  * An array of characters representing the next portion of the
143  * message.
144  *
145  * Returns:
146  * Nothing.
147  *
148  * Comments:
149  *
150  */
151  void
152  SHA1::Input(const unsigned char* message_array, unsigned length)
153  {
154  if (!length) {
155  return;
156  }
157 
158  if (Computed || Corrupted) {
159  Corrupted = true;
160  return;
161  }
162 
163  while (length-- && !Corrupted) {
164  Message_Block[Message_Block_Index++] = (*message_array & 0xFF);
165 
166  Length_Low += 8;
167  Length_Low &= 0xFFFFFFFF; // Force it to 32 bits
168  if (Length_Low == 0) {
169  Length_High++;
170  Length_High &= 0xFFFFFFFF; // Force it to 32 bits
171  if (Length_High == 0) {
172  Corrupted = true; // Message is too long
173  }
174  }
175 
176  if (Message_Block_Index == 64) {
178  }
179 
180  message_array++;
181  }
182  }
183 
184  /*
185  * Input
186  *
187  * Description:
188  * This function accepts an array of octets as the next portion of
189  * the message.
190  *
191  * Parameters:
192  * message_array: [in]
193  * An array of characters representing the next portion of the
194  * message.
195  * length: [in]
196  * The length of the message_array
197  *
198  * Returns:
199  * Nothing.
200  *
201  * Comments:
202  *
203  */
204  void
205  SHA1::Input(const char* message_array, unsigned length)
206  {
207  Input((unsigned char*)message_array, length);
208  }
209 
210  /*
211  * Input
212  *
213  * Description:
214  * This function accepts a single octets as the next message element.
215  *
216  * Parameters:
217  * message_element: [in]
218  * The next octet in the message.
219  *
220  * Returns:
221  * Nothing.
222  *
223  * Comments:
224  *
225  */
226  void
227  SHA1::Input(unsigned char message_element)
228  {
229  Input(&message_element, 1);
230  }
231 
232  /*
233  * Input
234  *
235  * Description:
236  * This function accepts a single octet as the next message element.
237  *
238  * Parameters:
239  * message_element: [in]
240  * The next octet in the message.
241  *
242  * Returns:
243  * Nothing.
244  *
245  * Comments:
246  *
247  */
248  void
249  SHA1::Input(char message_element)
250  {
251  Input((unsigned char*)&message_element, 1);
252  }
253 
254  /*
255  * operator<<
256  *
257  * Description:
258  * This operator makes it convenient to provide character strings to
259  * the SHA1 object for processing.
260  *
261  * Parameters:
262  * message_array: [in]
263  * The character array to take as input.
264  *
265  * Returns:
266  * A reference to the SHA1 object.
267  *
268  * Comments:
269  * Each character is assumed to hold 8 bits of information.
270  *
271  */
272  SHA1&
273  SHA1::operator<<(const char* message_array)
274  {
275  const char* p = message_array;
276 
277  while (*p) {
278  Input(*p);
279  p++;
280  }
281 
282  return *this;
283  }
284 
285  /*
286  * operator<<
287  *
288  * Description:
289  * This operator makes it convenient to provide character strings to
290  * the SHA1 object for processing.
291  *
292  * Parameters:
293  * message_array: [in]
294  * The character array to take as input.
295  *
296  * Returns:
297  * A reference to the SHA1 object.
298  *
299  * Comments:
300  * Each character is assumed to hold 8 bits of information.
301  *
302  */
303  SHA1&
304  SHA1::operator<<(const unsigned char* message_array)
305  {
306  const unsigned char* p = message_array;
307 
308  while (*p) {
309  Input(*p);
310  p++;
311  }
312 
313  return *this;
314  }
315 
316  /*
317  * operator<<
318  *
319  * Description:
320  * This function provides the next octet in the message.
321  *
322  * Parameters:
323  * message_element: [in]
324  * The next octet in the message
325  *
326  * Returns:
327  * A reference to the SHA1 object.
328  *
329  * Comments:
330  * The character is assumed to hold 8 bits of information.
331  *
332  */
333  SHA1&
334  SHA1::operator<<(const char message_element)
335  {
336  Input((unsigned char*)&message_element, 1);
337 
338  return *this;
339  }
340 
341  /*
342  * operator<<
343  *
344  * Description:
345  * This function provides the next octet in the message.
346  *
347  * Parameters:
348  * message_element: [in]
349  * The next octet in the message
350  *
351  * Returns:
352  * A reference to the SHA1 object.
353  *
354  * Comments:
355  * The character is assumed to hold 8 bits of information.
356  *
357  */
358  SHA1&
359  SHA1::operator<<(const unsigned char message_element)
360  {
361  Input(&message_element, 1);
362 
363  return *this;
364  }
365 
366  /*
367  * ProcessMessageBlock
368  *
369  * Description:
370  * This function will process the next 512 bits of the message
371  * stored in the Message_Block array.
372  *
373  * Parameters:
374  * None.
375  *
376  * Returns:
377  * Nothing.
378  *
379  * Comments:
380  * Many of the variable names in this function, especially the single
381  * character names, were used because those were the names used
382  * in the publication.
383  *
384  */
385  void
387  {
388  const unsigned K[] = {// Constants defined for SHA-1
389  0x5A827999,
390  0x6ED9EBA1,
391  0x8F1BBCDC,
392  0xCA62C1D6};
393  int t; // Loop counter
394  unsigned temp; // Temporary word value
395  unsigned W[80]; // Word sequence
396  unsigned A, B, C, D, E; // Word buffers
397 
398  /*
399  * Initialize the first 16 words in the array W
400  */
401  for (t = 0; t < 16; t++) {
402  W[t] = ((unsigned)Message_Block[t * 4]) << 24;
403  W[t] |= ((unsigned)Message_Block[t * 4 + 1]) << 16;
404  W[t] |= ((unsigned)Message_Block[t * 4 + 2]) << 8;
405  W[t] |= ((unsigned)Message_Block[t * 4 + 3]);
406  }
407 
408  for (t = 16; t < 80; t++) {
409  W[t] = CircularShift(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]);
410  }
411 
412  A = H[0];
413  B = H[1];
414  C = H[2];
415  D = H[3];
416  E = H[4];
417 
418  for (t = 0; t < 20; t++) {
419  temp = CircularShift(5, A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
420  temp &= 0xFFFFFFFF;
421  E = D;
422  D = C;
423  C = CircularShift(30, B);
424  B = A;
425  A = temp;
426  }
427 
428  for (t = 20; t < 40; t++) {
429  temp = CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[1];
430  temp &= 0xFFFFFFFF;
431  E = D;
432  D = C;
433  C = CircularShift(30, B);
434  B = A;
435  A = temp;
436  }
437 
438  for (t = 40; t < 60; t++) {
439  temp =
440  CircularShift(5, A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
441  temp &= 0xFFFFFFFF;
442  E = D;
443  D = C;
444  C = CircularShift(30, B);
445  B = A;
446  A = temp;
447  }
448 
449  for (t = 60; t < 80; t++) {
450  temp = CircularShift(5, A) + (B ^ C ^ D) + E + W[t] + K[3];
451  temp &= 0xFFFFFFFF;
452  E = D;
453  D = C;
454  C = CircularShift(30, B);
455  B = A;
456  A = temp;
457  }
458 
459  H[0] = (H[0] + A) & 0xFFFFFFFF;
460  H[1] = (H[1] + B) & 0xFFFFFFFF;
461  H[2] = (H[2] + C) & 0xFFFFFFFF;
462  H[3] = (H[3] + D) & 0xFFFFFFFF;
463  H[4] = (H[4] + E) & 0xFFFFFFFF;
464 
466  }
467 
468  /*
469  * PadMessage
470  *
471  * Description:
472  * According to the standard, the message must be padded to an even
473  * 512 bits. The first padding bit must be a '1'. The last 64 bits
474  * represent the length of the original message. All bits in between
475  * should be 0. This function will pad the message according to those
476  * rules by filling the message_block array accordingly. It will also
477  * call ProcessMessageBlock() appropriately. When it returns, it
478  * can be assumed that the message digest has been computed.
479  *
480  * Parameters:
481  * None.
482  *
483  * Returns:
484  * Nothing.
485  *
486  * Comments:
487  *
488  */
489  void
491  {
492  /*
493  * Check to see if the current message block is too small to hold
494  * the initial padding bits and length. If so, we will pad the
495  * block, process it, and then continue padding into a second block.
496  */
497  if (Message_Block_Index > 55) {
499  while (Message_Block_Index < 64) {
501  }
502 
504 
505  while (Message_Block_Index < 56) {
507  }
508  } else {
510  while (Message_Block_Index < 56) {
512  }
513  }
514 
515  /*
516  * Store the message length as the last 8 octets
517  */
518  Message_Block[56] = (Length_High >> 24) & 0xFF;
519  Message_Block[57] = (Length_High >> 16) & 0xFF;
520  Message_Block[58] = (Length_High >> 8) & 0xFF;
521  Message_Block[59] = (Length_High)&0xFF;
522  Message_Block[60] = (Length_Low >> 24) & 0xFF;
523  Message_Block[61] = (Length_Low >> 16) & 0xFF;
524  Message_Block[62] = (Length_Low >> 8) & 0xFF;
525  Message_Block[63] = (Length_Low)&0xFF;
526 
528  }
529 
530  /*
531  * CircularShift
532  *
533  * Description:
534  * This member function will perform a circular shifting operation.
535  *
536  * Parameters:
537  * bits: [in]
538  * The number of bits to shift (1-31)
539  * word: [in]
540  * The value to shift (assumes a 32-bit integer)
541  *
542  * Returns:
543  * The shifted value.
544  *
545  * Comments:
546  *
547  */
548  unsigned
549  SHA1::CircularShift(int bits, unsigned word)
550  {
551  return ((word << bits) & 0xFFFFFFFF) | ((word & 0xFFFFFFFF) >> (32 - bits));
552  }
553 
554 } // end of namespace mf
unsigned Length_Low
Definition: sha1.h:74
unsigned Length_High
Definition: sha1.h:75
int Message_Block_Index
Definition: sha1.h:78
void Reset()
Definition: sha1.cpp:78
unsigned char Message_Block[64]
Definition: sha1.h:77
unsigned H[5]
Definition: sha1.h:72
void PadMessage()
Definition: sha1.cpp:490
#define D
Debug message.
Definition: tclscanner.cpp:775
unsigned CircularShift(int bits, unsigned word)
Definition: sha1.cpp:549
bool Computed
Definition: sha1.h:80
p
Definition: test.py:223
bool Corrupted
Definition: sha1.h:81
void Input(const unsigned char *message_array, unsigned length)
Definition: sha1.cpp:152
bool Result(unsigned *message_digest_array)
Definition: sha1.cpp:113
void ProcessMessageBlock()
Definition: sha1.cpp:386
E
Definition: 018_def.c:13
#define A
Definition: memgrp.cpp:38
SHA1 & operator<<(const char *message_array)
Definition: sha1.cpp:273
union ptb::content::word::word word