The SHA-1, produces a 160-bit message digest for a given 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 "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 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 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.
Definition in file sha1.cpp.
#include "stdmisc.h"
#include <stdio.h>
#include <string.h>
#include <string>
#include <map>
#include <vector>
#include "nel/misc/sha1.h"
#include "nel/misc/file.h"
#include "nel/misc/path.h"
Go to the source code of this file.
Data Structures | |
| struct | SHA1Context |
Defines | |
| #define | SHA1CircularShift(bits, word) (((word) << (bits)) | ((word) >> (32-(bits)))) |
| #define | SHA1HashSize 20 |
Typedefs | |
| typedef short | int_least16_t |
| typedef SHA1Context | SHA1Context |
| typedef unsigned int | uint32_t |
| typedef unsigned char | uint8_t |
Enumerations | |
| enum | { shaSuccess = 0, shaNull, shaInputTooLong, shaStateError } |
Functions | |
| CHashKey | getSHA1 (const string &filename) |
| CHashKey | getSHA1 (const uint8 *buffer, uint32 size) |
| int | SHA1Input (SHA1Context *, const uint8_t *, unsigned int) |
| void | SHA1PadMessage (SHA1Context *) |
| void | SHA1ProcessMessageBlock (SHA1Context *) |
| int | SHA1Reset (SHA1Context *) |
| int | SHA1Result (SHA1Context *, uint8_t Message_Digest[20]) |
Variables | |
| uint8_t | buffer [bufferSize] |
| const int | bufferSize = 100000 |
|
|
Definition at line 235 of file sha1.cpp. Referenced by SHA1ProcessMessageBlock(). |
|
|
Definition at line 106 of file sha1.cpp. Referenced by SHA1Result(). |
|
|
|
|
|
|
|
|
Definition at line 87 of file sha1.cpp. Referenced by SHA1ProcessMessageBlock(). |
|
|
Definition at line 88 of file sha1.cpp. Referenced by getSHA1(). |
|
|
Definition at line 98 of file sha1.cpp.
00099 {
00100 shaSuccess = 0,
00101 shaNull, /* Null pointer parameter */
00102 shaInputTooLong, /* input data too long */
00103 shaStateError /* called Input after Result */
00104 };
|
|
|
Definition at line 170 of file sha1.cpp. References buffer, bufferSize, NLMISC::CIFile::close(), NLMISC::CIFile::eof(), NLMISC::CIFile::getFileSize(), min, nlwarning, NLMISC::CIFile::open(), NLMISC::CIFile::serialBuffer(), NLMISC::CIFile::setCacheFileOnOpen(), SHA1Input(), SHA1Reset(), SHA1Result(), sint, uint8, and uint8_t.
00171 {
00172 SHA1Context sha;
00173 int err;
00174 uint8_t Message_Digest[20];
00175
00176 //printf("reading '%s'\n", findData.cFileName);
00177 CIFile ifile;
00178 ifile.setCacheFileOnOpen(true);
00179 if (!ifile.open(CPath::lookup(filename)))
00180 {
00181 nlwarning ("SHA: Can't open the file '%s'", filename.c_str());
00182 return CHashKey();
00183 }
00184
00185 //FILE *fp = fopen (filename.c_str(), "rb");
00186 //if (fp == NULL) return CHashKey();
00187
00188 err = SHA1Reset(&sha);
00189 if (err)
00190 {
00191 nlwarning("SHA: SHA1Reset Error %d.\n", err );
00192 ifile.close ();
00193 return CHashKey();
00194 }
00195
00196 sint fs = ifile.getFileSize();
00197 sint n, read = 0;
00198 do
00199 {
00200 //bs = (int)fread (buffer, 1, bufferSize, fp);
00201 n = std::min (bufferSize, fs-read);
00202 //nlinfo ("read %d bytes", n);
00203 ifile.serialBuffer((uint8 *)buffer, n);
00204
00205 err = SHA1Input(&sha, buffer, n);
00206 if (err)
00207 {
00208 nlwarning ("SHA: SHA1Input Error %d.\n", err);
00209 ifile.close();
00210 return CHashKey();
00211 }
00212 read += n;
00213 }
00214 while (!ifile.eof());
00215
00216 ifile.close ();
00217
00218 err = SHA1Result(&sha, Message_Digest);
00219 if (err)
00220 {
00221 nlwarning("SHA: SHA1Result Error %d, could not compute message digest.\n", err );
00222 return CHashKey();
00223 }
00224
00225 CHashKey hk (Message_Digest);
00226 return hk;
00227 }
|
|
||||||||||||
|
Definition at line 139 of file sha1.cpp.
00140 {
00141 SHA1Context sha;
00142 int err;
00143 uint8_t Message_Digest[20];
00144
00145 err = SHA1Reset(&sha);
00146 if (err)
00147 {
00148 nlwarning("SHA: SHA1Reset Error %d.\n", err );
00149 return CHashKey();
00150 }
00151
00152 err = SHA1Input(&sha, (const uint8_t*)buffer, size);
00153 if (err)
00154 {
00155 nlwarning ("SHA: SHA1Input Error %d.\n", err);
00156 return CHashKey();
00157 }
00158
00159 err = SHA1Result(&sha, Message_Digest);
00160 if (err)
00161 {
00162 nlwarning("SHA: SHA1Result Error %d, could not compute message digest.\n", err );
00163 return CHashKey();
00164 }
00165
00166 CHashKey hk (Message_Digest);
00167 return hk;
00168 }
|
|
||||||||||||||||
|
Definition at line 357 of file sha1.cpp. References SHA1Context::Computed, SHA1Context::Corrupted, SHA1Context::Length_High, SHA1Context::Length_Low, SHA1Context::Message_Block, SHA1Context::Message_Block_Index, SHA1ProcessMessageBlock(), shaNull, shaStateError, and shaSuccess. Referenced by getSHA1().
00360 {
00361 if (!length)
00362 {
00363 return shaSuccess;
00364 }
00365
00366 if (!context || !message_array)
00367 {
00368 return shaNull;
00369 }
00370
00371 if (context->Computed)
00372 {
00373 context->Corrupted = shaStateError;
00374
00375 return shaStateError;
00376 }
00377
00378 if (context->Corrupted)
00379 {
00380 return context->Corrupted;
00381 }
00382 while(length-- && !context->Corrupted)
00383 {
00384 context->Message_Block[context->Message_Block_Index++] =
00385 (*message_array & 0xFF);
00386
00387 context->Length_Low += 8;
00388 if (context->Length_Low == 0)
00389 {
00390 context->Length_High++;
00391 if (context->Length_High == 0)
00392 {
00393 /* Message is too long */
00394 context->Corrupted = 1;
00395 }
00396 }
00397
00398 if (context->Message_Block_Index == 64)
00399 {
00400 SHA1ProcessMessageBlock(context);
00401 }
00402
00403 message_array++;
00404 }
00405
00406 return shaSuccess;
00407 }
|
|
|
Definition at line 541 of file sha1.cpp. References SHA1Context::Length_High, SHA1Context::Length_Low, SHA1Context::Message_Block, SHA1Context::Message_Block_Index, and SHA1ProcessMessageBlock(). Referenced by SHA1Result().
00542 {
00543 /*
00544 * Check to see if the current message block is too small to hold
00545 * the initial padding bits and length. If so, we will pad the
00546 * block, process it, and then continue padding into a second
00547 * block.
00548 */
00549 if (context->Message_Block_Index > 55)
00550 {
00551 context->Message_Block[context->Message_Block_Index++] = 0x80;
00552 while(context->Message_Block_Index < 64)
00553 {
00554 context->Message_Block[context->Message_Block_Index++] = 0;
00555 }
00556
00557 SHA1ProcessMessageBlock(context);
00558
00559 while(context->Message_Block_Index < 56)
00560 {
00561 context->Message_Block[context->Message_Block_Index++] = 0;
00562 }
00563 }
00564 else
00565 {
00566 context->Message_Block[context->Message_Block_Index++] = 0x80;
00567 while(context->Message_Block_Index < 56)
00568 {
00569
00570 context->Message_Block[context->Message_Block_Index++] = 0;
00571 }
00572 }
00573
00574 /*
00575 * Store the message length as the last 8 octets
00576 */
00577 context->Message_Block[56] = context->Length_High >> 24;
00578 context->Message_Block[57] = context->Length_High >> 16;
00579 context->Message_Block[58] = context->Length_High >> 8;
00580 context->Message_Block[59] = context->Length_High;
00581 context->Message_Block[60] = context->Length_Low >> 24;
00582 context->Message_Block[61] = context->Length_Low >> 16;
00583 context->Message_Block[62] = context->Length_Low >> 8;
00584 context->Message_Block[63] = context->Length_Low;
00585
00586 SHA1ProcessMessageBlock(context);
00587 }
|
|
|
Definition at line 430 of file sha1.cpp. References SHA1Context::Intermediate_Hash, SHA1Context::Message_Block, SHA1Context::Message_Block_Index, SHA1CircularShift, t, and uint32_t. Referenced by SHA1Input(), and SHA1PadMessage().
00431 {
00432 const uint32_t K[] = { /* Constants defined in SHA-1 */
00433 0x5A827999,
00434 0x6ED9EBA1,
00435 0x8F1BBCDC,
00436 0xCA62C1D6
00437 };
00438 int t; /* Loop counter */
00439 uint32_t temp; /* Temporary word value */
00440 uint32_t W[80]; /* Word sequence */
00441 uint32_t A, B, C, D, E; /* Word buffers */
00442
00443 /*
00444 * Initialize the first 16 words in the array W
00445 */
00446 for(t = 0; t < 16; t++)
00447 {
00448 W[t] = context->Message_Block[t * 4] << 24;
00449 W[t] |= context->Message_Block[t * 4 + 1] << 16;
00450 W[t] |= context->Message_Block[t * 4 + 2] << 8;
00451 W[t] |= context->Message_Block[t * 4 + 3];
00452 }
00453
00454 for(t = 16; t < 80; t++)
00455 {
00456 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
00457 }
00458
00459 A = context->Intermediate_Hash[0];
00460 B = context->Intermediate_Hash[1];
00461 C = context->Intermediate_Hash[2];
00462 D = context->Intermediate_Hash[3];
00463 E = context->Intermediate_Hash[4];
00464
00465 for(t = 0; t < 20; t++)
00466 {
00467 temp = SHA1CircularShift(5,A) +
00468 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
00469 E = D;
00470 D = C;
00471 C = SHA1CircularShift(30,B);
00472
00473 B = A;
00474 A = temp;
00475 }
00476
00477 for(t = 20; t < 40; t++)
00478 {
00479 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
00480 E = D;
00481 D = C;
00482 C = SHA1CircularShift(30,B);
00483 B = A;
00484 A = temp;
00485 }
00486
00487 for(t = 40; t < 60; t++)
00488 {
00489 temp = SHA1CircularShift(5,A) +
00490 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
00491 E = D;
00492 D = C;
00493 C = SHA1CircularShift(30,B);
00494 B = A;
00495 A = temp;
00496 }
00497
00498 for(t = 60; t < 80; t++)
00499 {
00500 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
00501 E = D;
00502 D = C;
00503 C = SHA1CircularShift(30,B);
00504 B = A;
00505 A = temp;
00506 }
00507
00508 context->Intermediate_Hash[0] += A;
00509 context->Intermediate_Hash[1] += B;
00510 context->Intermediate_Hash[2] += C;
00511 context->Intermediate_Hash[3] += D;
00512 context->Intermediate_Hash[4] += E;
00513
00514 context->Message_Block_Index = 0;
00515 }
|
|
|
Definition at line 257 of file sha1.cpp. References SHA1Context::Computed, SHA1Context::Corrupted, SHA1Context::Intermediate_Hash, SHA1Context::Length_High, SHA1Context::Length_Low, SHA1Context::Message_Block_Index, shaNull, and shaSuccess. Referenced by getSHA1().
00258 {
00259 if (!context)
00260 {
00261 return shaNull;
00262 }
00263
00264 context->Length_Low = 0;
00265 context->Length_High = 0;
00266 context->Message_Block_Index = 0;
00267
00268 context->Intermediate_Hash[0] = 0x67452301;
00269 context->Intermediate_Hash[1] = 0xEFCDAB89;
00270 context->Intermediate_Hash[2] = 0x98BADCFE;
00271 context->Intermediate_Hash[3] = 0x10325476;
00272 context->Intermediate_Hash[4] = 0xC3D2E1F0;
00273
00274 context->Computed = 0;
00275 context->Corrupted = 0;
00276
00277 return shaSuccess;
00278 }
|
|
||||||||||||
|
Definition at line 299 of file sha1.cpp. References SHA1Context::Computed, SHA1Context::Corrupted, SHA1Context::Intermediate_Hash, SHA1Context::Length_High, SHA1Context::Length_Low, SHA1Context::Message_Block, SHA1HashSize, SHA1PadMessage(), shaNull, and shaSuccess. Referenced by getSHA1().
00301 {
00302 int i;
00303
00304 if (!context || !Message_Digest)
00305 {
00306 return shaNull;
00307 }
00308
00309 if (context->Corrupted)
00310 {
00311 return context->Corrupted;
00312 }
00313
00314 if (!context->Computed)
00315 {
00316 SHA1PadMessage(context);
00317 for(i=0; i<64; ++i)
00318 {
00319 /* message may be sensitive, clear it out */
00320 context->Message_Block[i] = 0;
00321 }
00322 context->Length_Low = 0; /* and clear length */
00323 context->Length_High = 0;
00324 context->Computed = 1;
00325
00326 }
00327
00328 for(i = 0; i < SHA1HashSize; ++i)
00329 {
00330 Message_Digest[i] = context->Intermediate_Hash[i>>2]
00331 >> 8 * ( 3 - ( i & 0x03 ) );
00332 }
00333
00334 return shaSuccess;
00335 }
|
|
|
|
|
|
Definition at line 95 of file sha1.cpp. Referenced by getSHA1(). |
1.3.6