#include <asterisk/sha1.h>
Go to the source code of this file.
Defines | |
#define | SHA1_ROTL(bits, word) (((word) << (bits)) | ((word) >> (32-(bits)))) |
#define | SHA1AddLength(context, length) |
Functions | |
int | SHA1FinalBits (SHA1Context *context, uint8_t message_bits, unsigned int length) |
SHA1FinalBits Add in any final bits of the message. | |
static void | SHA1Finalize (SHA1Context *context, uint8_t Pad_Byte) |
This helper function finishes off the digest calculations. | |
int | SHA1Input (SHA1Context *context, const uint8_t *message_array, unsigned length) |
SHA1Input. | |
static void | SHA1PadMessage (SHA1Context *context, uint8_t Pad_Byte) |
Pad message to be 512 bits. | |
static void | SHA1ProcessMessageBlock (SHA1Context *context) |
Process the next 512 bits of the message stored in the Message_Block array. | |
int | SHA1Reset (SHA1Context *context) |
SHA1Reset. | |
int | SHA1Result (SHA1Context *context, uint8_t Message_Digest[SHA1HashSize]) |
Variables | |
static uint32_t | addTemp |
Copyright (c) 2011 IETF Trust and the persons identified as authors of the code. All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Description: 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 algorithm produces a 160-bit message digest for 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 "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. This implementation uses SHA1Input() to hash the bits 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.
Definition in file sha1.c.
#define SHA1_ROTL | ( | bits, | |||
word | ) | (((word) << (bits)) | ((word) >> (32-(bits)))) |
Define the SHA1 circular left shift macro
Definition at line 74 of file sha1.c.
Referenced by SHA1ProcessMessageBlock().
#define SHA1AddLength | ( | context, | |||
length | ) |
Value:
(addTemp = (context)->Length_Low, \ (context)->Corrupted = \ (((context)->Length_Low += (length)) < addTemp) && \ (++(context)->Length_High == 0) ? shaInputTooLong \ : (context)->Corrupted )
Definition at line 82 of file sha1.c.
Referenced by SHA1FinalBits(), and SHA1Input().
int SHA1FinalBits | ( | SHA1Context * | context, | |
uint8_t | message_bits, | |||
unsigned int | length | |||
) |
SHA1FinalBits Add in any final bits of the message.
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. |
Definition at line 179 of file sha1.c.
References context, SHA1AddLength, SHA1Finalize(), shaBadParam, shaNull, shaStateError, and shaSuccess.
00181 { 00182 static uint8_t masks[8] = { 00183 /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, 00184 /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, 00185 /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, 00186 /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE 00187 }; 00188 00189 static uint8_t markbit[8] = { 00190 /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, 00191 /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, 00192 /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, 00193 /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 00194 }; 00195 00196 if (!context) 00197 return shaNull; 00198 if (!length) 00199 return shaSuccess; 00200 if (context->Corrupted) 00201 return context->Corrupted; 00202 if (context->Computed) 00203 return context->Corrupted = shaStateError; 00204 if (length >= 8) 00205 return context->Corrupted = shaBadParam; 00206 00207 SHA1AddLength(context, length); 00208 SHA1Finalize(context, 00209 (uint8_t) ((message_bits & masks[length]) | 00210 markbit[length])); 00211 00212 return context->Corrupted; 00213 }
static void SHA1Finalize | ( | SHA1Context * | context, | |
uint8_t | Pad_Byte | |||
) | [static] |
This helper function finishes off the digest calculations.
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. |
Definition at line 346 of file sha1.c.
References context, SHA1_Message_Block_Size, and SHA1PadMessage().
Referenced by SHA1FinalBits(), and SHA1Result().
00347 { 00348 int i; 00349 SHA1PadMessage(context, Pad_Byte); 00350 /* message may be sensitive, clear it out */ 00351 for (i = 0; i < SHA1_Message_Block_Size; ++i) { 00352 context->Message_Block[i] = 0; 00353 } 00354 context->Length_High = 0; /* and clear length */ 00355 context->Length_Low = 0; 00356 context->Computed = 1; 00357 }
int SHA1Input | ( | SHA1Context * | context, | |
const uint8_t * | message_array, | |||
unsigned | length | |||
) |
SHA1Input.
context | [in/out] The SHA context to update | |
message_array | [in] An array of characters representing the next portion of the message. | |
length | [in] The length of the message in message_array. This function accepts an array of octets as the next portion of the message. |
Definition at line 133 of file sha1.c.
References context, SHA1_Message_Block_Size, SHA1AddLength, SHA1ProcessMessageBlock(), shaNull, shaStateError, and shaSuccess.
00135 { 00136 if (!context) { 00137 return shaNull; 00138 } 00139 if (!length) { 00140 return shaSuccess; 00141 } 00142 if (!message_array) { 00143 return shaNull; 00144 } 00145 00146 if (context->Computed) { 00147 context->Corrupted = shaStateError; 00148 return shaStateError; 00149 } 00150 00151 if (context->Corrupted) { 00152 return context->Corrupted; 00153 } 00154 00155 while (length--) { 00156 context->Message_Block[context->Message_Block_Index++] = 00157 *message_array; 00158 00159 if ((SHA1AddLength(context, 8) == shaSuccess) && 00160 (context->Message_Block_Index == SHA1_Message_Block_Size)) 00161 SHA1ProcessMessageBlock(context); 00162 00163 message_array++; 00164 } 00165 00166 return context->Corrupted; 00167 }
static void SHA1PadMessage | ( | SHA1Context * | context, | |
uint8_t | Pad_Byte | |||
) | [static] |
Pad message to be 512 bits.
context | [in/out] The context to pad. | |
Pad_byte | [in] Last padding byte. |
Definition at line 374 of file sha1.c.
References context, SHA1_Message_Block_Size, and SHA1ProcessMessageBlock().
Referenced by SHA1Finalize().
00375 { 00376 /* 00377 * Check to see if the current message block is too small to hold 00378 * the initial padding bits and length. If so, we will pad the 00379 * block, process it, and then continue padding into a second 00380 * block. 00381 */ 00382 if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) { 00383 context->Message_Block[context->Message_Block_Index++] = Pad_Byte; 00384 while (context->Message_Block_Index < SHA1_Message_Block_Size) { 00385 context->Message_Block[context->Message_Block_Index++] = 0; 00386 } 00387 00388 SHA1ProcessMessageBlock(context); 00389 } else 00390 context->Message_Block[context->Message_Block_Index++] = Pad_Byte; 00391 00392 while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8)) { 00393 context->Message_Block[context->Message_Block_Index++] = 0; 00394 } 00395 00396 /* 00397 * Store the message length as the last 8 octets 00398 */ 00399 context->Message_Block[56] = (uint8_t) (context->Length_High >> 24); 00400 context->Message_Block[57] = (uint8_t) (context->Length_High >> 16); 00401 context->Message_Block[58] = (uint8_t) (context->Length_High >> 8); 00402 context->Message_Block[59] = (uint8_t) (context->Length_High); 00403 context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24); 00404 context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16); 00405 context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8); 00406 context->Message_Block[63] = (uint8_t) (context->Length_Low); 00407 00408 SHA1ProcessMessageBlock(context); 00409 }
static void SHA1ProcessMessageBlock | ( | SHA1Context * | context | ) | [static] |
Process the next 512 bits of the message stored in the Message_Block array.
context | [in/out] The SHA context to update |
Definition at line 260 of file sha1.c.
References context, SHA1_ROTL, SHA_Ch, SHA_Maj, and SHA_Parity.
Referenced by SHA1Input(), and SHA1PadMessage().
00261 { 00262 /* Constants defined in FIPS 180-3, section 4.2.1 */ 00263 const uint32_t K[4] = { 00264 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 00265 }; 00266 int t; /* Loop counter */ 00267 uint32_t temp; /* Temporary word value */ 00268 uint32_t W[80]; /* Word sequence */ 00269 uint32_t A, B, C, D, E; /* Word buffers */ 00270 00271 /* 00272 * Initialize the first 16 words in the array W 00273 */ 00274 for (t = 0; t < 16; t++) { 00275 W[t] = ((uint32_t) context->Message_Block[t * 4]) << 24; 00276 W[t] |= ((uint32_t) context->Message_Block[t * 4 + 1]) << 16; 00277 W[t] |= ((uint32_t) context->Message_Block[t * 4 + 2]) << 8; 00278 W[t] |= ((uint32_t) context->Message_Block[t * 4 + 3]); 00279 } 00280 00281 for (t = 16; t < 80; t++) { 00282 W[t] = SHA1_ROTL(1, W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]); 00283 } 00284 00285 A = context->Intermediate_Hash[0]; 00286 B = context->Intermediate_Hash[1]; 00287 C = context->Intermediate_Hash[2]; 00288 D = context->Intermediate_Hash[3]; 00289 E = context->Intermediate_Hash[4]; 00290 00291 for (t = 0; t < 20; t++) { 00292 temp = SHA1_ROTL(5, A) + SHA_Ch(B, C, D) + E + W[t] + K[0]; 00293 E = D; 00294 D = C; 00295 C = SHA1_ROTL(30, B); 00296 B = A; 00297 A = temp; 00298 } 00299 00300 for (t = 20; t < 40; t++) { 00301 temp = SHA1_ROTL(5, A) + SHA_Parity(B, C, D) + E + W[t] + K[1]; 00302 E = D; 00303 D = C; 00304 C = SHA1_ROTL(30, B); 00305 B = A; 00306 A = temp; 00307 } 00308 00309 for (t = 40; t < 60; t++) { 00310 temp = SHA1_ROTL(5, A) + SHA_Maj(B, C, D) + E + W[t] + K[2]; 00311 E = D; 00312 D = C; 00313 C = SHA1_ROTL(30, B); 00314 B = A; 00315 A = temp; 00316 } 00317 00318 for (t = 60; t < 80; t++) { 00319 temp = SHA1_ROTL(5, A) + SHA_Parity(B, C, D) + E + W[t] + K[3]; 00320 E = D; 00321 D = C; 00322 C = SHA1_ROTL(30, B); 00323 B = A; 00324 A = temp; 00325 } 00326 00327 context->Intermediate_Hash[0] += A; 00328 context->Intermediate_Hash[1] += B; 00329 context->Intermediate_Hash[2] += C; 00330 context->Intermediate_Hash[3] += D; 00331 context->Intermediate_Hash[4] += E; 00332 00333 context->Message_Block_Index = 0; 00334 }
int SHA1Reset | ( | SHA1Context * | context | ) |
SHA1Reset.
context | the context to be reset. This function will initialize the SHA1Context in preparation for computing a new SHA1 message digest. |
Definition at line 101 of file sha1.c.
References context, shaNull, and shaSuccess.
Referenced by ast_sha1_hash().
00102 { 00103 if (!context) { 00104 return shaNull; 00105 } 00106 00107 context->Length_High = context->Length_Low = 0; 00108 context->Message_Block_Index = 0; 00109 00110 /* Initial Hash Values: FIPS 180-3 section 5.3.1 */ 00111 context->Intermediate_Hash[0] = 0x67452301; 00112 context->Intermediate_Hash[1] = 0xEFCDAB89; 00113 context->Intermediate_Hash[2] = 0x98BADCFE; 00114 context->Intermediate_Hash[3] = 0x10325476; 00115 context->Intermediate_Hash[4] = 0xC3D2E1F0; 00116 00117 context->Computed = 0; 00118 context->Corrupted = shaSuccess; 00119 00120 return shaSuccess; 00121 }
int SHA1Result | ( | SHA1Context * | context, | |
uint8_t | Message_Digest[SHA1HashSize] | |||
) |
Definition at line 226 of file sha1.c.
References context, SHA1Finalize(), shaNull, and shaSuccess.
Referenced by ast_sha1_hash().
00227 { 00228 int i; 00229 00230 if (!context) { 00231 return shaNull; 00232 } 00233 if (!Message_Digest) { 00234 return shaNull; 00235 } 00236 if (context->Corrupted) { 00237 return context->Corrupted; 00238 } 00239 00240 if (!context->Computed) { 00241 SHA1Finalize(context, 0x80); 00242 } 00243 00244 for (i = 0; i < SHA1HashSize; ++i) { 00245 Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i >> 2] 00246 >> (8 * (3 - (i & 0x03)))); 00247 } 00248 00249 return shaSuccess; 00250 }