|
|
|
|
@@ -14,10 +14,10 @@ Still 100% Public Domain
|
|
|
|
|
|
|
|
|
|
Corrected a problem which generated improper hash values on 16 bit machines
|
|
|
|
|
Routine SHA1Update changed from
|
|
|
|
|
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int
|
|
|
|
|
void SHA1Update(P_SHA1_CTX* context, unsigned char* data, unsigned int
|
|
|
|
|
len)
|
|
|
|
|
to
|
|
|
|
|
void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned
|
|
|
|
|
void SHA1Update(P_SHA1_CTX* context, unsigned char* data, unsigned
|
|
|
|
|
long len)
|
|
|
|
|
|
|
|
|
|
The 'len' parameter was declared an int which works fine on 32 bit machines.
|
|
|
|
|
@@ -99,9 +99,9 @@ A million repetitions of "a"
|
|
|
|
|
#include <stdint.h>
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "sha1.h"
|
|
|
|
|
#include "p_sha1.h"
|
|
|
|
|
|
|
|
|
|
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
|
|
|
|
|
void P_SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
|
|
|
|
|
|
|
|
|
|
#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
|
|
|
|
|
|
|
|
|
|
@@ -126,7 +126,7 @@ void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef VERBOSE /* SAK */
|
|
|
|
|
void SHAPrintContext(SHA1_CTX *context, char *msg){
|
|
|
|
|
void SHAPrintContext(P_P_SHA1_CTX *context, char *msg){
|
|
|
|
|
printf("%s (%d,%d) %x %x %x %x %x\n",
|
|
|
|
|
msg,
|
|
|
|
|
context->count[0], context->count[1],
|
|
|
|
|
@@ -139,7 +139,7 @@ void SHAPrintContext(SHA1_CTX *context, char *msg){
|
|
|
|
|
#endif /* VERBOSE */
|
|
|
|
|
|
|
|
|
|
/* Hash a single 512-bit block. This is the core of the algorithm. */
|
|
|
|
|
void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
|
|
|
|
|
void P_SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
|
|
|
|
|
{
|
|
|
|
|
uint32_t a, b, c, d, e;
|
|
|
|
|
typedef union {
|
|
|
|
|
@@ -198,7 +198,7 @@ void SHA1_Transform(uint32_t state[5], const uint8_t buffer[64])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* SHA1Init - Initialize new context */
|
|
|
|
|
void SHA1_Init(SHA1_CTX* context)
|
|
|
|
|
void P_SHA1_Init(P_SHA1_CTX* context)
|
|
|
|
|
{
|
|
|
|
|
/* SHA1 initialization constants */
|
|
|
|
|
context->state[0] = 0x67452301;
|
|
|
|
|
@@ -211,7 +211,7 @@ void SHA1_Init(SHA1_CTX* context)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Run your data through this. */
|
|
|
|
|
void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
|
|
|
|
|
void P_SHA1_Update(P_SHA1_CTX* context, const uint8_t* data, const size_t len)
|
|
|
|
|
{
|
|
|
|
|
size_t i, j;
|
|
|
|
|
|
|
|
|
|
@@ -224,9 +224,9 @@ void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
|
|
|
|
|
context->count[1] += (len >> 29);
|
|
|
|
|
if ((j + len) > 63) {
|
|
|
|
|
memcpy(&context->buffer[j], data, (i = 64-j));
|
|
|
|
|
SHA1_Transform(context->state, context->buffer);
|
|
|
|
|
P_SHA1_Transform(context->state, context->buffer);
|
|
|
|
|
for ( ; i + 63 < len; i += 64) {
|
|
|
|
|
SHA1_Transform(context->state, data + i);
|
|
|
|
|
P_SHA1_Transform(context->state, data + i);
|
|
|
|
|
}
|
|
|
|
|
j = 0;
|
|
|
|
|
}
|
|
|
|
|
@@ -240,7 +240,7 @@ void SHA1_Update(SHA1_CTX* context, const uint8_t* data, const size_t len)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Add padding and return the message digest. */
|
|
|
|
|
void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
|
|
|
|
|
void P_SHA1_Final(P_SHA1_CTX* context, uint8_t digest[P_SHA1_DIGEST_SIZE])
|
|
|
|
|
{
|
|
|
|
|
uint32_t i;
|
|
|
|
|
uint8_t finalcount[8];
|
|
|
|
|
@@ -249,12 +249,12 @@ void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
|
|
|
|
|
finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)]
|
|
|
|
|
>> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */
|
|
|
|
|
}
|
|
|
|
|
SHA1_Update(context, (uint8_t *)"\200", 1);
|
|
|
|
|
P_SHA1_Update(context, (uint8_t *)"\200", 1);
|
|
|
|
|
while ((context->count[0] & 504) != 448) {
|
|
|
|
|
SHA1_Update(context, (uint8_t *)"\0", 1);
|
|
|
|
|
P_SHA1_Update(context, (uint8_t *)"\0", 1);
|
|
|
|
|
}
|
|
|
|
|
SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
|
|
|
|
|
for (i = 0; i < SHA1_DIGEST_SIZE; i++) {
|
|
|
|
|
P_SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */
|
|
|
|
|
for (i = 0; i < P_SHA1_DIGEST_SIZE; i++) {
|
|
|
|
|
digest[i] = (uint8_t)
|
|
|
|
|
((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255);
|
|
|
|
|
}
|
|
|
|
|
@@ -267,7 +267,7 @@ void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
|
|
|
|
|
memset(finalcount, 0, 8); /* SWR */
|
|
|
|
|
|
|
|
|
|
#ifdef SHA1HANDSOFF /* make SHA1Transform overwrite its own static vars */
|
|
|
|
|
SHA1_Transform(context->state, context->buffer);
|
|
|
|
|
P_SHA1_Transform(context->state, context->buffer);
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -277,8 +277,8 @@ void SHA1_Final(SHA1_CTX* context, uint8_t digest[SHA1_DIGEST_SIZE])
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
|
{
|
|
|
|
|
int i, j;
|
|
|
|
|
SHA1_CTX context;
|
|
|
|
|
unsigned char digest[SHA1_DIGEST_SIZE], buffer[16384];
|
|
|
|
|
P_SHA1_CTX context;
|
|
|
|
|
unsigned char digest[P_SHA1_DIGEST_SIZE], buffer[16384];
|
|
|
|
|
FILE* file;
|
|
|
|
|
|
|
|
|
|
if (argc > 2) {
|
|
|
|
|
@@ -303,7 +303,7 @@ FILE* file;
|
|
|
|
|
}
|
|
|
|
|
SHA1_Final(&context, digest);
|
|
|
|
|
fclose(file);
|
|
|
|
|
for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
|
|
|
|
|
for (i = 0; i < P_SHA1_DIGEST_SIZE/4; i++) {
|
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
|
|
|
printf("%02X", digest[i*4+j]);
|
|
|
|
|
}
|
|
|
|
|
@@ -327,12 +327,12 @@ static char *test_results[] = {
|
|
|
|
|
"84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1",
|
|
|
|
|
"34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F"};
|
|
|
|
|
|
|
|
|
|
void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output)
|
|
|
|
|
void digest_to_hex(const uint8_t digest[P_SHA1_DIGEST_SIZE], char *output)
|
|
|
|
|
{
|
|
|
|
|
int i,j;
|
|
|
|
|
char *c = output;
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < SHA1_DIGEST_SIZE/4; i++) {
|
|
|
|
|
for (i = 0; i < P_SHA1_DIGEST_SIZE/4; i++) {
|
|
|
|
|
for (j = 0; j < 4; j++) {
|
|
|
|
|
sprintf(c,"%02X", digest[i*4+j]);
|
|
|
|
|
c += 2;
|
|
|
|
|
@@ -346,16 +346,16 @@ void digest_to_hex(const uint8_t digest[SHA1_DIGEST_SIZE], char *output)
|
|
|
|
|
int main(int argc, char** argv)
|
|
|
|
|
{
|
|
|
|
|
int k;
|
|
|
|
|
SHA1_CTX context;
|
|
|
|
|
P_SHA1_CTX context;
|
|
|
|
|
uint8_t digest[20];
|
|
|
|
|
char output[80];
|
|
|
|
|
|
|
|
|
|
fprintf(stdout, "verifying SHA-1 implementation... ");
|
|
|
|
|
|
|
|
|
|
for (k = 0; k < 2; k++){
|
|
|
|
|
SHA1_Init(&context);
|
|
|
|
|
SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k]));
|
|
|
|
|
SHA1_Final(&context, digest);
|
|
|
|
|
P_SHA1_Init(&context);
|
|
|
|
|
P_SHA1_Update(&context, (uint8_t*)test_data[k], strlen(test_data[k]));
|
|
|
|
|
P_SHA1_Final(&context, digest);
|
|
|
|
|
digest_to_hex(digest, output);
|
|
|
|
|
|
|
|
|
|
if (strcmp(output, test_results[k])) {
|
|
|
|
|
@@ -367,10 +367,10 @@ int main(int argc, char** argv)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
/* million 'a' vector we feed separately */
|
|
|
|
|
SHA1_Init(&context);
|
|
|
|
|
P_SHA1_Init(&context);
|
|
|
|
|
for (k = 0; k < 1000000; k++)
|
|
|
|
|
SHA1_Update(&context, (uint8_t*)"a", 1);
|
|
|
|
|
SHA1_Final(&context, digest);
|
|
|
|
|
P_SHA1_Update(&context, (uint8_t*)"a", 1);
|
|
|
|
|
P_SHA1_Final(&context, digest);
|
|
|
|
|
digest_to_hex(digest, output);
|
|
|
|
|
if (strcmp(output, test_results[2])) {
|
|
|
|
|
fprintf(stdout, "FAIL\n");
|