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