1/* 2SHA-1 in C 3By Steve Reid <sreid@sea-to-sky.net> 4100% Public Domain 5 6----------------- 7Modified 7/98 8By James H. Brown <jbrown@burgoyne.com> 9Still 100% Public Domain 10 11Corrected a problem which generated improper hash values on 16 bit machines 12Routine SHA1Update changed from 13 void SHA1Update(SHA_CTX* context, unsigned char* data, unsigned int 14len) 15to 16 void SHA1Update(SHA_CTX* context, unsigned char* data, unsigned 17long len) 18 19The 'len' parameter was declared an int which works fine on 32 bit machines. 20However, on 16 bit machines an int is too small for the shifts being done 21against 22it. This caused the hash function to generate incorrect values if len was 23greater than 8191 (8K - 1) due to the 'len << 3' on line 3 of SHA1Update(). 24 25Since the file IO in main() reads 16K at a time, any file 8K or larger would 26be guaranteed to generate the wrong hash (e.g. Test Vector #3, a million 27"a"s). 28 29I also changed the declaration of variables i & j in SHA1Update to 30unsigned long from unsigned int for the same reason. 31 32These changes should make no difference to any 32 bit implementations since 33an 34int and a long are the same size in those environments. 35 36-- 37I also corrected a few compiler warnings generated by Borland C. 381. Added #include <process.h> for exit() prototype 392. Removed unused variable 'j' in SHA1Final 403. Changed exit(0) to return(0) at end of main. 41 42ALL changes I made can be located by searching for comments containing 'JHB' 43----------------- 44Modified 8/98 45By Steve Reid <sreid@sea-to-sky.net> 46Still 100% public domain 47 481- Removed #include <process.h> and used return() instead of exit() 492- Fixed overwriting of finalcount in SHA1Final() (discovered by Chris Hall) 503- Changed email address from steve@edmweb.com to sreid@sea-to-sky.net 51 52----------------- 53Modified 4/01 54By Saul Kravitz <Saul.Kravitz@celera.com> 55Still 100% PD 56Modified to run on Compaq Alpha hardware. 57 58----------------- 59Modified 07/2002 60By Ralph Giles <giles@ghostscript.com> 61Still 100% public domain 62modified for use with stdint types, autoconf 63code cleanup, removed attribution comments 64switched SHA1Final() argument order for consistency 65use SHA1_ prefix for public api 66move public api to sha1.h 67*/ 68 69/* 7011/2016 adapted for CivetWeb: 71 include sha1.h in sha1.c, 72 rename to sha1.inl 73 remove unused #ifdef sections 74 make endian independent 75 align buffer to 4 bytes 76 remove unused variable assignments 77*/ 78 79/* 80Test Vectors (from FIPS PUB 180-1) 81"abc" 82 A9993E36 4706816A BA3E2571 7850C26C 9CD0D89D 83"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" 84 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 85A million repetitions of "a" 86 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F 87*/ 88 89#include <stdint.h> 90#include <string.h> 91 92typedef struct { 93 uint32_t state[5]; 94 uint32_t count[2]; 95 uint8_t buffer[64]; 96} SHA_CTX; 97 98#define SHA1_DIGEST_SIZE 20 99 100#define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) 101 102/* blk0() and blk() perform the initial expand. */ 103/* I got the idea of expanding during the round function from SSLeay */ 104 105 106typedef union { 107 uint8_t c[64]; 108 uint32_t l[16]; 109} CHAR64LONG16; 110 111 112static uint32_t 113blk0(CHAR64LONG16 *block, int i) 114{ 115 static const uint32_t n = 1u; 116 if ((*((uint8_t *)(&n))) == 1) { 117 /* little endian / intel byte order */ 118 block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) 119 | (rol(block->l[i], 8) & 0x00FF00FF); 120 } 121 return block->l[i]; 122} 123 124#define blk(block, i) \ 125 ((block)->l[(i)&15] = \ 126 rol((block)->l[((i) + 13) & 15] ^ (block)->l[((i) + 8) & 15] \ 127 ^ (block)->l[((i) + 2) & 15] ^ (block)->l[(i)&15], \ 128 1)) 129 130/* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 131#define R0(v, w, x, y, z, i) \ 132 z += ((w & (x ^ y)) ^ y) + blk0(block, i) + 0x5A827999 + rol(v, 5); \ 133 w = rol(w, 30); 134#define R1(v, w, x, y, z, i) \ 135 z += ((w & (x ^ y)) ^ y) + blk(block, i) + 0x5A827999 + rol(v, 5); \ 136 w = rol(w, 30); 137#define R2(v, w, x, y, z, i) \ 138 z += (w ^ x ^ y) + blk(block, i) + 0x6ED9EBA1 + rol(v, 5); \ 139 w = rol(w, 30); 140#define R3(v, w, x, y, z, i) \ 141 z += (((w | x) & y) | (w & x)) + blk(block, i) + 0x8F1BBCDC + rol(v, 5); \ 142 w = rol(w, 30); 143#define R4(v, w, x, y, z, i) \ 144 z += (w ^ x ^ y) + blk(block, i) + 0xCA62C1D6 + rol(v, 5); \ 145 w = rol(w, 30); 146 147 148/* Hash a single 512-bit block. This is the core of the algorithm. */ 149static void 150SHA1_Transform(uint32_t state[5], const uint8_t buffer[64]) 151{ 152 uint32_t a, b, c, d, e; 153 154 /* Must use an aligned, read/write buffer */ 155 CHAR64LONG16 block[1]; 156 memcpy(block, buffer, sizeof(block)); 157 158 /* Copy context->state[] to working vars */ 159 a = state[0]; 160 b = state[1]; 161 c = state[2]; 162 d = state[3]; 163 e = state[4]; 164 165 /* 4 rounds of 20 operations each. Loop unrolled. */ 166 R0(a, b, c, d, e, 0); 167 R0(e, a, b, c, d, 1); 168 R0(d, e, a, b, c, 2); 169 R0(c, d, e, a, b, 3); 170 R0(b, c, d, e, a, 4); 171 R0(a, b, c, d, e, 5); 172 R0(e, a, b, c, d, 6); 173 R0(d, e, a, b, c, 7); 174 R0(c, d, e, a, b, 8); 175 R0(b, c, d, e, a, 9); 176 R0(a, b, c, d, e, 10); 177 R0(e, a, b, c, d, 11); 178 R0(d, e, a, b, c, 12); 179 R0(c, d, e, a, b, 13); 180 R0(b, c, d, e, a, 14); 181 R0(a, b, c, d, e, 15); 182 R1(e, a, b, c, d, 16); 183 R1(d, e, a, b, c, 17); 184 R1(c, d, e, a, b, 18); 185 R1(b, c, d, e, a, 19); 186 R2(a, b, c, d, e, 20); 187 R2(e, a, b, c, d, 21); 188 R2(d, e, a, b, c, 22); 189 R2(c, d, e, a, b, 23); 190 R2(b, c, d, e, a, 24); 191 R2(a, b, c, d, e, 25); 192 R2(e, a, b, c, d, 26); 193 R2(d, e, a, b, c, 27); 194 R2(c, d, e, a, b, 28); 195 R2(b, c, d, e, a, 29); 196 R2(a, b, c, d, e, 30); 197 R2(e, a, b, c, d, 31); 198 R2(d, e, a, b, c, 32); 199 R2(c, d, e, a, b, 33); 200 R2(b, c, d, e, a, 34); 201 R2(a, b, c, d, e, 35); 202 R2(e, a, b, c, d, 36); 203 R2(d, e, a, b, c, 37); 204 R2(c, d, e, a, b, 38); 205 R2(b, c, d, e, a, 39); 206 R3(a, b, c, d, e, 40); 207 R3(e, a, b, c, d, 41); 208 R3(d, e, a, b, c, 42); 209 R3(c, d, e, a, b, 43); 210 R3(b, c, d, e, a, 44); 211 R3(a, b, c, d, e, 45); 212 R3(e, a, b, c, d, 46); 213 R3(d, e, a, b, c, 47); 214 R3(c, d, e, a, b, 48); 215 R3(b, c, d, e, a, 49); 216 R3(a, b, c, d, e, 50); 217 R3(e, a, b, c, d, 51); 218 R3(d, e, a, b, c, 52); 219 R3(c, d, e, a, b, 53); 220 R3(b, c, d, e, a, 54); 221 R3(a, b, c, d, e, 55); 222 R3(e, a, b, c, d, 56); 223 R3(d, e, a, b, c, 57); 224 R3(c, d, e, a, b, 58); 225 R3(b, c, d, e, a, 59); 226 R4(a, b, c, d, e, 60); 227 R4(e, a, b, c, d, 61); 228 R4(d, e, a, b, c, 62); 229 R4(c, d, e, a, b, 63); 230 R4(b, c, d, e, a, 64); 231 R4(a, b, c, d, e, 65); 232 R4(e, a, b, c, d, 66); 233 R4(d, e, a, b, c, 67); 234 R4(c, d, e, a, b, 68); 235 R4(b, c, d, e, a, 69); 236 R4(a, b, c, d, e, 70); 237 R4(e, a, b, c, d, 71); 238 R4(d, e, a, b, c, 72); 239 R4(c, d, e, a, b, 73); 240 R4(b, c, d, e, a, 74); 241 R4(a, b, c, d, e, 75); 242 R4(e, a, b, c, d, 76); 243 R4(d, e, a, b, c, 77); 244 R4(c, d, e, a, b, 78); 245 R4(b, c, d, e, a, 79); 246 247 /* Add the working vars back into context.state[] */ 248 state[0] += a; 249 state[1] += b; 250 state[2] += c; 251 state[3] += d; 252 state[4] += e; 253} 254 255 256/* SHA1Init - Initialize new context */ 257SHA_API void 258SHA1_Init(SHA_CTX *context) 259{ 260 /* SHA1 initialization constants */ 261 context->state[0] = 0x67452301; 262 context->state[1] = 0xEFCDAB89; 263 context->state[2] = 0x98BADCFE; 264 context->state[3] = 0x10325476; 265 context->state[4] = 0xC3D2E1F0; 266 context->count[0] = context->count[1] = 0; 267} 268 269 270SHA_API void 271SHA1_Update(SHA_CTX *context, const uint8_t *data, const uint32_t len) 272{ 273 uint32_t i, j; 274 275 j = context->count[0]; 276 if ((context->count[0] += (len << 3)) < j) { 277 context->count[1]++; 278 } 279 context->count[1] += (len >> 29); 280 j = (j >> 3) & 63; 281 if ((j + len) > 63) { 282 i = 64 - j; 283 memcpy(&context->buffer[j], data, i); 284 SHA1_Transform(context->state, context->buffer); 285 for (; i + 63 < len; i += 64) { 286 SHA1_Transform(context->state, &data[i]); 287 } 288 j = 0; 289 } else { 290 i = 0; 291 } 292 memcpy(&context->buffer[j], &data[i], len - i); 293} 294 295 296/* Add padding and return the message digest. */ 297SHA_API void 298SHA1_Final(unsigned char *digest, SHA_CTX *context) 299{ 300 uint32_t i; 301 uint8_t finalcount[8]; 302 303 for (i = 0; i < 8; i++) { 304 finalcount[i] = 305 (uint8_t)((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) 306 & 255); /* Endian independent */ 307 } 308 SHA1_Update(context, (uint8_t *)"\x80", 1); 309 while ((context->count[0] & 504) != 448) { 310 SHA1_Update(context, (uint8_t *)"\x00", 1); 311 } 312 SHA1_Update(context, finalcount, 8); /* Should cause a SHA1_Transform() */ 313 for (i = 0; i < SHA1_DIGEST_SIZE; i++) { 314 digest[i] = 315 (uint8_t)((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); 316 } 317 318 /* Wipe variables */ 319 memset(context, '\0', sizeof(*context)); 320} 321 322 323/* End of sha1.inl */ 324