Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of libMiMic by
sha1.c
00001 /* 00002 SHA-1 in C 00003 By Steve Reid <steve@edmweb.com> 00004 100% Public Domain 00005 00006 Test Vectors (from FIPS PUB 180-1) 00007 "abc" 00008 A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 00009 "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 00010 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 00011 A million repetitions of "a" 00012 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 00013 */ 00014 /** 00015 * modified by nyatla 00016 * Still public domain. 00017 */ 00018 00019 /* #define LITTLE_ENDIAN * This should be #define'd if true. */ 00020 /* #define SHA1HANDSOFF * Copies data before messing with it. */ 00021 00022 #include <stdio.h> 00023 #include <string.h> 00024 #include "sha1.h" 00025 #include "NyLPC_config.h" 00026 00027 00028 # if UIP_BYTE_ORDER == NyLPC_ENDIAN_BIG 00029 # else 00030 # define LITTLE_ENDIAN 1 00031 #endif 00032 00033 00034 00035 00036 /* 00037 void SHA1Transform(unsigned long state[5], unsigned char buffer[64]); 00038 void SHA1Init(SHA1_CTX* context); 00039 void SHA1Update(SHA1_CTX* context, unsigned char* data, unsigned int len); 00040 void SHA1Final(unsigned char digest[20], SHA1_CTX* context); 00041 */ 00042 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 00043 00044 /* blk0() and blk() perform the initial expand. */ 00045 /* I got the idea of expanding during the round function from SSLeay */ 00046 #ifdef LITTLE_ENDIAN 00047 #define blk0(i) (block->l[i] = (rol(block->l[i],24)&0xFF00FF00) \ 00048 |(rol(block->l[i],8)&0x00FF00FF)) 00049 #else 00050 #define blk0(i) block->l[i] 00051 #endif 00052 #define blk(i) (block->l[i&15] = rol(block->l[(i+13)&15]^block->l[(i+8)&15] \ 00053 ^block->l[(i+2)&15]^block->l[i&15],1)) 00054 00055 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 00056 #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 00057 #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 00058 #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 00059 #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 00060 #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 00061 00062 00063 00064 /* Hash a single 512-bit block. This is the core of the algorithm. */ 00065 #define SHA1HANDSOFF 1 00066 void SHA1Transform(unsigned long state[5],const unsigned char buffer[64]) 00067 { 00068 unsigned long a, b, c, d, e; 00069 typedef union { 00070 unsigned char c[64]; 00071 unsigned long l[16]; 00072 } CHAR64LONG16; 00073 CHAR64LONG16* block; 00074 #ifdef SHA1HANDSOFF 00075 static unsigned char workspace[64]; 00076 block = (CHAR64LONG16*)workspace; 00077 memcpy(block, buffer, 64); 00078 #else 00079 block = (CHAR64LONG16*)buffer; 00080 #endif 00081 /* Copy context->state[] to working vars */ 00082 a = state[0]; 00083 b = state[1]; 00084 c = state[2]; 00085 d = state[3]; 00086 e = state[4]; 00087 /* 4 rounds of 20 operations each. Loop unrolled. */ 00088 R0(a,b,c,d,e, 0); R0(e,a,b,c,d, 1); R0(d,e,a,b,c, 2); R0(c,d,e,a,b, 3); 00089 R0(b,c,d,e,a, 4); R0(a,b,c,d,e, 5); R0(e,a,b,c,d, 6); R0(d,e,a,b,c, 7); 00090 R0(c,d,e,a,b, 8); R0(b,c,d,e,a, 9); R0(a,b,c,d,e,10); R0(e,a,b,c,d,11); 00091 R0(d,e,a,b,c,12); R0(c,d,e,a,b,13); R0(b,c,d,e,a,14); R0(a,b,c,d,e,15); 00092 R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); 00093 R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); 00094 R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); 00095 R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); 00096 R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); 00097 R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); 00098 R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); 00099 R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); 00100 R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); 00101 R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); 00102 R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); 00103 R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); 00104 R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); 00105 R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); 00106 R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); 00107 R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); 00108 /* Add the working vars back into context.state[] */ 00109 state[0] += a; 00110 state[1] += b; 00111 state[2] += c; 00112 state[3] += d; 00113 state[4] += e; 00114 /* Wipe variables */ 00115 a = b = c = d = e = 0; 00116 } 00117 00118 00119 /* SHA1Init - Initialize new context */ 00120 00121 void SHA1Init(SHA1_CTX* context) 00122 { 00123 /* SHA1 initialization constants */ 00124 context->state[0] = 0x67452301; 00125 context->state[1] = 0xEFCDAB89; 00126 context->state[2] = 0x98BADCFE; 00127 context->state[3] = 0x10325476; 00128 context->state[4] = 0xC3D2E1F0; 00129 context->count[0] = context->count[1] = 0; 00130 } 00131 00132 00133 /* Run your data through this. */ 00134 00135 void SHA1Update(SHA1_CTX* context,const void* data, unsigned int len) 00136 { 00137 unsigned int i, j; 00138 00139 j = (context->count[0] >> 3) & 63; 00140 if ((context->count[0] += len << 3) < (len << 3)) context->count[1]++; 00141 context->count[1] += (len >> 29); 00142 if ((j + len) > 63) { 00143 memcpy(&context->buffer[j], data, (i = 64-j)); 00144 SHA1Transform(context->state, context->buffer); 00145 for ( ; i + 63 < len; i += 64) { 00146 SHA1Transform(context->state, ((const unsigned char*)data)+i); 00147 } 00148 j = 0; 00149 } 00150 else i = 0; 00151 memcpy(&context->buffer[j], ((const unsigned char*)data)+i, len - i); 00152 } 00153 00154 00155 /* Add padding and return the message digest. */ 00156 00157 void SHA1Final(unsigned char digest[20], SHA1_CTX* context) 00158 { 00159 unsigned long i, j; 00160 unsigned char finalcount[8]; 00161 00162 for (i = 0; i < 8; i++) { 00163 finalcount[i] = (unsigned char)((context->count[((i >= 4) ? 0 : 1)] 00164 >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 00165 } 00166 SHA1Update(context, (unsigned char *)"\200", 1); 00167 while ((context->count[0] & 504) != 448) { 00168 SHA1Update(context, (unsigned char *)"\0", 1); 00169 } 00170 SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ 00171 for (i = 0; i < 20; i++) { 00172 digest[i] = (unsigned char) 00173 ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 00174 } 00175 /* Wipe variables */ 00176 i = j = 0; 00177 memset(context->buffer, 0, 64); 00178 memset(context->state, 0, 20); 00179 memset(context->count, 0, 8); 00180 memset(&finalcount, 0, 8); 00181 #ifdef SHA1HANDSOFF /* make SHA1Transform overwrite it's own static vars */ 00182 SHA1Transform(context->state, context->buffer); 00183 #endif 00184 } 00185 00186 00187 /*************************************************************/ 00188 //#define TEST_SHA1 00189 #ifdef TEST_SHA1 00190 00191 int main(int argc, char** argv) 00192 { 00193 int i, j; 00194 SHA1_CTX context; 00195 unsigned char digest[20], buffer[16384]; 00196 FILE* file; 00197 00198 if (argc > 2) { 00199 puts("Public domain SHA-1 implementation - by Steve Reid <steve@edmweb.com>"); 00200 puts("Produces the SHA-1 hash of a file, or stdin if no file is specified."); 00201 exit(0); 00202 } 00203 if (argc < 2) { 00204 file = stdin; 00205 } 00206 else { 00207 if (!(file = fopen(argv[1], "rb"))) { 00208 fputs("Unable to open file.", stderr); 00209 exit(-1); 00210 } 00211 } 00212 SHA1Init(&context); 00213 while (!feof(file)) { /* note: what if ferror(file) */ 00214 i = fread(buffer, 1, 16384, file); 00215 SHA1Update(&context, buffer, i); 00216 } 00217 SHA1Final(digest, &context); 00218 fclose(file); 00219 for (i = 0; i < 5; i++) { 00220 for (j = 0; j < 4; j++) { 00221 printf("%02X", digest[i*4+j]); 00222 } 00223 putchar(' '); 00224 } 00225 putchar('\n'); 00226 exit(0); 00227 } 00228 #endif 00229
Generated on Tue Jul 12 2022 16:22:59 by
