Line data Source code
1 : /************************* sha224-256.c ************************/
2 : /***************** See RFC 6234 for details. *******************/
3 : /* Copyright (c) 2011 IETF Trust and the persons identified as */
4 : /* authors of the code. All rights reserved. */
5 : /* See sha.h for terms of use and redistribution. */
6 :
7 : /*
8 : * Description:
9 : * This file implements the Secure Hash Algorithms SHA-224 and
10 : * SHA-256 as defined in the U.S. National Institute of Standards
11 : * and Technology Federal Information Processing Standards
12 : * Publication (FIPS PUB) 180-3 published in October 2008
13 : * and formerly defined in its predecessors, FIPS PUB 180-1
14 : * and FIP PUB 180-2.
15 : *
16 : * A combined document showing all algorithms is available at
17 : * http://csrc.nist.gov/publications/fips/
18 : * fips180-3/fips180-3_final.pdf
19 : *
20 : * The SHA-224 and SHA-256 algorithms produce 224-bit and 256-bit
21 : * message digests for a given data stream. It should take about
22 : * 2**n steps to find a message with the same digest as a given
23 : * message and 2**(n/2) to find any two messages with the same
24 : * digest, when n is the digest size in bits. Therefore, this
25 : * algorithm can serve as a means of providing a
26 : * "fingerprint" for a message.
27 : *
28 : * Portability Issues:
29 : * SHA-224 and SHA-256 are defined in terms of 32-bit "words".
30 : * This code uses <stdint.h> (included via "sha.h") to define 32-
31 : * and 8-bit unsigned integer types. If your C compiler does not
32 : * support 32-bit unsigned integers, this code is not
33 : * appropriate.
34 : *
35 : * Caveats:
36 : * SHA-224 and SHA-256 are designed to work with messages less
37 : * than 2^64 bits long. This implementation uses SHA224/256Input()
38 : * to hash the bits that are a multiple of the size of an 8-bit
39 : * octet, and then optionally uses SHA224/256FinalBits()
40 : * to hash the final few bits of the input.
41 : */
42 :
43 : #include "sha.h"
44 : #include "sha-private.h"
45 :
46 : /* Define the SHA shift, rotate left, and rotate right macros */
47 : #define SHA256_SHR(bits,word) ((word) >> (bits))
48 : #define SHA256_ROTL(bits,word) \
49 : (((word) << (bits)) | ((word) >> (32-(bits))))
50 : #define SHA256_ROTR(bits,word) \
51 : (((word) >> (bits)) | ((word) << (32-(bits))))
52 :
53 : /* Define the SHA SIGMA and sigma macros */
54 : #define SHA256_SIGMA0(word) \
55 : (SHA256_ROTR( 2,word) ^ SHA256_ROTR(13,word) ^ SHA256_ROTR(22,word))
56 : #define SHA256_SIGMA1(word) \
57 : (SHA256_ROTR( 6,word) ^ SHA256_ROTR(11,word) ^ SHA256_ROTR(25,word))
58 : #define SHA256_sigma0(word) \
59 : (SHA256_ROTR( 7,word) ^ SHA256_ROTR(18,word) ^ SHA256_SHR( 3,word))
60 : #define SHA256_sigma1(word) \
61 : (SHA256_ROTR(17,word) ^ SHA256_ROTR(19,word) ^ SHA256_SHR(10,word))
62 :
63 : /*
64 : * Add "length" to the length.
65 : * Set Corrupted when overflow has occurred.
66 : */
67 : #define SHA224_256AddLength(context, length) \
68 : (addTemp = (context)->Length_Low, (context)->Corrupted = \
69 : (((context)->Length_Low += (length)) < addTemp) && \
70 : (++(context)->Length_High == 0) ? shaInputTooLong : \
71 : (context)->Corrupted )
72 :
73 : /* Local Function Prototypes */
74 : static int SHA224_256Reset(SHA256Context *context, uint32_t *H0);
75 : static void SHA224_256ProcessMessageBlock(SHA256Context *context);
76 : static void SHA224_256Finalize(SHA256Context *context,
77 : uint8_t Pad_Byte);
78 : static void SHA224_256PadMessage(SHA256Context *context,
79 : uint8_t Pad_Byte);
80 : static int SHA224_256ResultN(SHA256Context *context,
81 : uint8_t Message_Digest[ ], int HashSize);
82 :
83 : /* Initial Hash Values: FIPS 180-3 section 5.3.2 */
84 : static uint32_t SHA224_H0[SHA256HashSize/4] = {
85 : 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939,
86 : 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4
87 : };
88 :
89 : /* Initial Hash Values: FIPS 180-3 section 5.3.3 */
90 : static uint32_t SHA256_H0[SHA256HashSize/4] = {
91 : 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
92 : 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
93 : };
94 :
95 : /*
96 : * SHA224Reset
97 : *
98 : * Description:
99 : * This function will initialize the SHA224Context in preparation
100 : * for computing a new SHA224 message digest.
101 : *
102 : * Parameters:
103 : * context: [in/out]
104 : * The context to reset.
105 : *
106 : * Returns:
107 : * sha Error Code.
108 : */
109 1 : int SHA224Reset(SHA224Context *context)
110 : {
111 1 : return SHA224_256Reset(context, SHA224_H0);
112 : }
113 :
114 : /*
115 : * SHA224Input
116 : *
117 : * Description:
118 : * This function accepts an array of octets as the next portion
119 : * of the message.
120 : *
121 : * Parameters:
122 : * context: [in/out]
123 : * The SHA context to update.
124 : * message_array[ ]: [in]
125 : * An array of octets representing the next portion of
126 : * the message.
127 : * length: [in]
128 : * The length of the message in message_array.
129 : *
130 : * Returns:
131 : * sha Error Code.
132 : *
133 : */
134 1 : int SHA224Input(SHA224Context *context, const uint8_t *message_array,
135 : unsigned int length)
136 : {
137 1 : return SHA256Input(context, message_array, length);
138 : }
139 :
140 : /*
141 : * SHA224FinalBits
142 : *
143 : * Description:
144 : * This function will add in any final bits of the message.
145 : *
146 : * Parameters:
147 : * context: [in/out]
148 : * The SHA context to update.
149 : * message_bits: [in]
150 : * The final bits of the message, in the upper portion of the
151 : * byte. (Use 0b###00000 instead of 0b00000### to input the
152 : * three bits ###.)
153 : * length: [in]
154 : * The number of bits in message_bits, between 1 and 7.
155 : *
156 : * Returns:
157 : * sha Error Code.
158 : */
159 0 : int SHA224FinalBits(SHA224Context *context,
160 : uint8_t message_bits, unsigned int length)
161 : {
162 0 : return SHA256FinalBits(context, message_bits, length);
163 : }
164 :
165 : /*
166 : * SHA224Result
167 : *
168 : * Description:
169 : * This function will return the 224-bit message digest
170 : * into the Message_Digest array provided by the caller.
171 : * NOTE:
172 : * The first octet of hash is stored in the element with index 0,
173 : * the last octet of hash in the element with index 27.
174 : *
175 : * Parameters:
176 : * context: [in/out]
177 : * The context to use to calculate the SHA hash.
178 : * Message_Digest[ ]: [out]
179 : * Where the digest is returned.
180 : *
181 : * Returns:
182 : * sha Error Code.
183 : */
184 1 : int SHA224Result(SHA224Context *context,
185 : uint8_t Message_Digest[SHA224HashSize])
186 : {
187 1 : return SHA224_256ResultN(context, Message_Digest, SHA224HashSize);
188 : }
189 :
190 : /*
191 : * SHA256Reset
192 : *
193 : * Description:
194 : * This function will initialize the SHA256Context in preparation
195 : * for computing a new SHA256 message digest.
196 : *
197 : * Parameters:
198 : * context: [in/out]
199 : * The context to reset.
200 : *
201 : * Returns:
202 : * sha Error Code.
203 : */
204 1 : int SHA256Reset(SHA256Context *context)
205 : {
206 1 : return SHA224_256Reset(context, SHA256_H0);
207 : }
208 :
209 : /*
210 : * SHA256Input
211 : *
212 : * Description:
213 : * This function accepts an array of octets as the next portion
214 : * of the message.
215 : *
216 : * Parameters:
217 : * context: [in/out]
218 : * The SHA context to update.
219 : * message_array[ ]: [in]
220 : * An array of octets representing the next portion of
221 : * the message.
222 : * length: [in]
223 : * The length of the message in message_array.
224 : *
225 : * Returns:
226 : * sha Error Code.
227 : */
228 2 : int SHA256Input(SHA256Context *context, const uint8_t *message_array,
229 : unsigned int length)
230 : {
231 2 : if (!context) return shaNull;
232 2 : if (!length) return shaSuccess;
233 2 : if (!message_array) return shaNull;
234 2 : if (context->Computed) return context->Corrupted = shaStateError;
235 2 : if (context->Corrupted) return context->Corrupted;
236 :
237 16 : while (length--) {
238 14 : context->Message_Block[context->Message_Block_Index++] =
239 14 : *message_array;
240 :
241 14 : uint32_t addTemp;
242 14 : if ((SHA224_256AddLength(context, 8) == shaSuccess) &&
243 : (context->Message_Block_Index == SHA256_Message_Block_Size))
244 0 : SHA224_256ProcessMessageBlock(context);
245 :
246 14 : message_array++;
247 : }
248 :
249 2 : return context->Corrupted;
250 :
251 : }
252 :
253 : /*
254 : * SHA256FinalBits
255 : *
256 : * Description:
257 : * This function will add in any final bits of the message.
258 : *
259 : * Parameters:
260 : * context: [in/out]
261 : * The SHA context to update.
262 : * message_bits: [in]
263 : * The final bits of the message, in the upper portion of the
264 : * byte. (Use 0b###00000 instead of 0b00000### to input the
265 : * three bits ###.)
266 : * length: [in]
267 : * The number of bits in message_bits, between 1 and 7.
268 : *
269 : * Returns:
270 : * sha Error Code.
271 : */
272 0 : int SHA256FinalBits(SHA256Context *context,
273 : uint8_t message_bits, unsigned int length)
274 : {
275 0 : static uint8_t masks[8] = {
276 : /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
277 : /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
278 : /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
279 : /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
280 : };
281 0 : static uint8_t markbit[8] = {
282 : /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
283 : /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
284 : /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
285 : /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
286 : };
287 :
288 0 : if (!context) return shaNull;
289 0 : if (!length) return shaSuccess;
290 0 : if (context->Corrupted) return context->Corrupted;
291 0 : if (context->Computed) return context->Corrupted = shaStateError;
292 0 : if (length >= 8) return context->Corrupted = shaBadParam;
293 :
294 0 : uint32_t addTemp;
295 0 : SHA224_256AddLength(context, length);
296 0 : SHA224_256Finalize(context, (uint8_t)
297 0 : ((message_bits & masks[length]) | markbit[length]));
298 :
299 0 : return context->Corrupted;
300 : }
301 :
302 : /*
303 : * SHA256Result
304 : *
305 : * Description:
306 : * This function will return the 256-bit message digest
307 : * into the Message_Digest array provided by the caller.
308 : * NOTE:
309 : * The first octet of hash is stored in the element with index 0,
310 : * the last octet of hash in the element with index 31.
311 : *
312 : * Parameters:
313 : * context: [in/out]
314 : * The context to use to calculate the SHA hash.
315 : * Message_Digest[ ]: [out]
316 : * Where the digest is returned.
317 : *
318 : * Returns:
319 : * sha Error Code.
320 : */
321 1 : int SHA256Result(SHA256Context *context,
322 : uint8_t Message_Digest[SHA256HashSize])
323 : {
324 1 : return SHA224_256ResultN(context, Message_Digest, SHA256HashSize);
325 : }
326 :
327 : /*
328 : * SHA224_256Reset
329 : *
330 : * Description:
331 : * This helper function will initialize the SHA256Context in
332 : * preparation for computing a new SHA-224 or SHA-256 message digest.
333 : *
334 : * Parameters:
335 : * context: [in/out]
336 : * The context to reset.
337 : * H0[ ]: [in]
338 : * The initial hash value array to use.
339 : *
340 : * Returns:
341 : * sha Error Code.
342 : */
343 2 : static int SHA224_256Reset(SHA256Context *context, uint32_t *H0)
344 : {
345 2 : if (!context) return shaNull;
346 :
347 2 : context->Length_High = context->Length_Low = 0;
348 2 : context->Message_Block_Index = 0;
349 :
350 2 : context->Intermediate_Hash[0] = H0[0];
351 2 : context->Intermediate_Hash[1] = H0[1];
352 2 : context->Intermediate_Hash[2] = H0[2];
353 2 : context->Intermediate_Hash[3] = H0[3];
354 2 : context->Intermediate_Hash[4] = H0[4];
355 2 : context->Intermediate_Hash[5] = H0[5];
356 2 : context->Intermediate_Hash[6] = H0[6];
357 2 : context->Intermediate_Hash[7] = H0[7];
358 :
359 2 : context->Computed = 0;
360 2 : context->Corrupted = shaSuccess;
361 :
362 2 : return shaSuccess;
363 : }
364 :
365 : /*
366 : * SHA224_256ProcessMessageBlock
367 : *
368 : * Description:
369 : * This helper function will process the next 512 bits of the
370 : * message stored in the Message_Block array.
371 : *
372 : * Parameters:
373 : * context: [in/out]
374 : * The SHA context to update.
375 : *
376 : * Returns:
377 : * Nothing.
378 : *
379 : * Comments:
380 : * Many of the variable names in this code, especially the
381 : * single character names, were used because those were the
382 : * names used in the Secure Hash Standard.
383 : */
384 2 : static void SHA224_256ProcessMessageBlock(SHA256Context *context)
385 : {
386 : /* Constants defined in FIPS 180-3, section 4.2.2 */
387 2 : static const uint32_t K[64] = {
388 : 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
389 : 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
390 : 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
391 : 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
392 : 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
393 : 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
394 : 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
395 : 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
396 : 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
397 : 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
398 : 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
399 : 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
400 : 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
401 : };
402 2 : int t, t4; /* Loop counter */
403 2 : uint32_t temp1, temp2; /* Temporary word value */
404 2 : uint32_t W[64]; /* Word sequence */
405 2 : uint32_t A, B, C, D, E, F, G, H; /* Word buffers */
406 :
407 : /*
408 : * Initialize the first 16 words in the array W
409 : */
410 34 : for (t = t4 = 0; t < 16; t++, t4 += 4)
411 32 : W[t] = (((uint32_t)context->Message_Block[t4]) << 24) |
412 32 : (((uint32_t)context->Message_Block[t4 + 1]) << 16) |
413 32 : (((uint32_t)context->Message_Block[t4 + 2]) << 8) |
414 32 : (((uint32_t)context->Message_Block[t4 + 3]));
415 :
416 98 : for (t = 16; t < 64; t++)
417 96 : W[t] = SHA256_sigma1(W[t-2]) + W[t-7] +
418 96 : SHA256_sigma0(W[t-15]) + W[t-16];
419 :
420 2 : A = context->Intermediate_Hash[0];
421 2 : B = context->Intermediate_Hash[1];
422 2 : C = context->Intermediate_Hash[2];
423 2 : D = context->Intermediate_Hash[3];
424 2 : E = context->Intermediate_Hash[4];
425 2 : F = context->Intermediate_Hash[5];
426 2 : G = context->Intermediate_Hash[6];
427 2 : H = context->Intermediate_Hash[7];
428 :
429 130 : for (t = 0; t < 64; t++) {
430 128 : temp1 = H + SHA256_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t];
431 128 : temp2 = SHA256_SIGMA0(A) + SHA_Maj(A,B,C);
432 128 : H = G;
433 128 : G = F;
434 128 : F = E;
435 128 : E = D + temp1;
436 128 : D = C;
437 128 : C = B;
438 128 : B = A;
439 128 : A = temp1 + temp2;
440 : }
441 :
442 2 : context->Intermediate_Hash[0] += A;
443 2 : context->Intermediate_Hash[1] += B;
444 2 : context->Intermediate_Hash[2] += C;
445 2 : context->Intermediate_Hash[3] += D;
446 2 : context->Intermediate_Hash[4] += E;
447 2 : context->Intermediate_Hash[5] += F;
448 2 : context->Intermediate_Hash[6] += G;
449 2 : context->Intermediate_Hash[7] += H;
450 :
451 2 : context->Message_Block_Index = 0;
452 2 : }
453 :
454 : /*
455 : * SHA224_256Finalize
456 : *
457 : * Description:
458 : * This helper function finishes off the digest calculations.
459 : *
460 : * Parameters:
461 : * context: [in/out]
462 : * The SHA context to update.
463 : * Pad_Byte: [in]
464 : * The last byte to add to the message block before the 0-padding
465 : * and length. This will contain the last bits of the message
466 : * followed by another single bit. If the message was an
467 : * exact multiple of 8-bits long, Pad_Byte will be 0x80.
468 : *
469 : * Returns:
470 : * sha Error Code.
471 : */
472 2 : static void SHA224_256Finalize(SHA256Context *context,
473 : uint8_t Pad_Byte)
474 : {
475 2 : int i;
476 2 : SHA224_256PadMessage(context, Pad_Byte);
477 : /* message may be sensitive, so clear it out */
478 132 : for (i = 0; i < SHA256_Message_Block_Size; ++i)
479 128 : context->Message_Block[i] = 0;
480 2 : context->Length_High = 0; /* and clear length */
481 2 : context->Length_Low = 0;
482 2 : context->Computed = 1;
483 2 : }
484 :
485 : /*
486 : * SHA224_256PadMessage
487 : *
488 : * Description:
489 : * According to the standard, the message must be padded to the next
490 : * even multiple of 512 bits. The first padding bit must be a '1'.
491 : * The last 64 bits represent the length of the original message.
492 : * All bits in between should be 0. This helper function will pad
493 : * the message according to those rules by filling the
494 : * Message_Block array accordingly. When it returns, it can be
495 : * assumed that the message digest has been computed.
496 : *
497 : * Parameters:
498 : * context: [in/out]
499 : * The context to pad.
500 : * Pad_Byte: [in]
501 : * The last byte to add to the message block before the 0-padding
502 : * and length. This will contain the last bits of the message
503 : * followed by another single bit. If the message was an
504 : * exact multiple of 8-bits long, Pad_Byte will be 0x80.
505 : *
506 : * Returns:
507 : * Nothing.
508 : */
509 2 : static void SHA224_256PadMessage(SHA256Context *context,
510 : uint8_t Pad_Byte)
511 : {
512 : /*
513 : * Check to see if the current message block is too small to hold
514 : * the initial padding bits and length. If so, we will pad the
515 : * block, process it, and then continue padding into a second
516 : * block.
517 : */
518 2 : if (context->Message_Block_Index >= (SHA256_Message_Block_Size-8)) {
519 0 : context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
520 0 : while (context->Message_Block_Index < SHA256_Message_Block_Size)
521 0 : context->Message_Block[context->Message_Block_Index++] = 0;
522 0 : SHA224_256ProcessMessageBlock(context);
523 : } else
524 2 : context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
525 :
526 98 : while (context->Message_Block_Index < (SHA256_Message_Block_Size-8))
527 96 : context->Message_Block[context->Message_Block_Index++] = 0;
528 :
529 : /*
530 : * Store the message length as the last 8 octets
531 : */
532 2 : context->Message_Block[56] = (uint8_t)(context->Length_High >> 24);
533 2 : context->Message_Block[57] = (uint8_t)(context->Length_High >> 16);
534 2 : context->Message_Block[58] = (uint8_t)(context->Length_High >> 8);
535 2 : context->Message_Block[59] = (uint8_t)(context->Length_High);
536 2 : context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24);
537 2 : context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16);
538 2 : context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8);
539 2 : context->Message_Block[63] = (uint8_t)(context->Length_Low);
540 :
541 2 : SHA224_256ProcessMessageBlock(context);
542 2 : }
543 :
544 : /*
545 : * SHA224_256ResultN
546 : *
547 : * Description:
548 : * This helper function will return the 224-bit or 256-bit message
549 : * digest into the Message_Digest array provided by the caller.
550 : * NOTE:
551 : * The first octet of hash is stored in the element with index 0,
552 : * the last octet of hash in the element with index 27/31.
553 : *
554 : * Parameters:
555 : * context: [in/out]
556 : * The context to use to calculate the SHA hash.
557 : * Message_Digest[ ]: [out]
558 : * Where the digest is returned.
559 : * HashSize: [in]
560 : * The size of the hash, either 28 or 32.
561 : *
562 : * Returns:
563 : * sha Error Code.
564 : */
565 2 : static int SHA224_256ResultN(SHA256Context *context,
566 : uint8_t Message_Digest[ ], int HashSize)
567 : {
568 2 : int i;
569 :
570 2 : if (!context) return shaNull;
571 2 : if (!Message_Digest) return shaNull;
572 2 : if (context->Corrupted) return context->Corrupted;
573 :
574 2 : if (!context->Computed)
575 2 : SHA224_256Finalize(context, 0x80);
576 :
577 62 : for (i = 0; i < HashSize; ++i)
578 60 : Message_Digest[i] = (uint8_t)
579 60 : (context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ));
580 :
581 : return shaSuccess;
582 : }
|