|
|
1.1 ! root 1: /* SHA-1 in C By Steve Reid <[email protected]> 100% Public Domain ! 2: ! 3: Test Vectors (from FIPS PUB 180-1) "abc" A9993E36 4706816A BA3E2571 7850C26C ! 4: 9CD0D89D "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" ! 5: 84983E44 1C3BD26E BAAE4AA1 F95129E5 E54670F1 A million repetitions of "a" ! 6: 34AA973C D4C4DAA4 F61EEB2B DBAD2731 6534016F */ ! 7: ! 8: /* #define LITTLE_ENDIAN * This should be #define'd if true. */ ! 9: ! 10: #include <string.h> ! 11: #include "endian.h" ! 12: #include "sha1.h" ! 13: ! 14: #pragma intrinsic(memset,memcpy) ! 15: ! 16: #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits)))) ! 17: ! 18: /* blk0() and blk() perform the initial expand. */ ! 19: /* I got the idea of expanding during the round function from SSLeay */ ! 20: #ifdef LITTLE_ENDIAN ! 21: #define blk0(i) (block.l[i] = (rol(block.l[i],24)&0xFF00FF00) \ ! 22: |(rol(block.l[i],8)&0x00FF00FF)) ! 23: #else ! 24: #define blk0(i) block.l[i] ! 25: #endif ! 26: #define blk(i) (block.l[i&15] = rol(block.l[(i+13)&15]^block.l[(i+8)&15] \ ! 27: ^block.l[(i+2)&15]^block.l[i&15],1)) ! 28: ! 29: /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ ! 30: #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); ! 31: #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); ! 32: #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); ! 33: #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); ! 34: #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); ! 35: ! 36: ! 37: /* Hash a single 512-bit block. This is the core of the algorithm. */ ! 38: ! 39: void ! 40: SHA1TRANSFORM (unsigned long state[5], unsigned char buffer[64]) ! 41: { ! 42: unsigned long a, b, c, d, e; ! 43: typedef union ! 44: { ! 45: unsigned char c[64]; ! 46: unsigned long l[16]; ! 47: } CHAR64LONG16; ! 48: CHAR64LONG16 block; ! 49: ! 50: memcpy (&block, buffer, 64); ! 51: ! 52: /* Copy context->state[] to working vars */ ! 53: a = state[0]; ! 54: b = state[1]; ! 55: c = state[2]; ! 56: d = state[3]; ! 57: e = state[4]; ! 58: /* 4 rounds of 20 operations each. Loop unrolled. */ ! 59: R0 (a, b, c, d, e, 0); ! 60: R0 (e, a, b, c, d, 1); ! 61: R0 (d, e, a, b, c, 2); ! 62: R0 (c, d, e, a, b, 3); ! 63: R0 (b, c, d, e, a, 4); ! 64: R0 (a, b, c, d, e, 5); ! 65: R0 (e, a, b, c, d, 6); ! 66: R0 (d, e, a, b, c, 7); ! 67: R0 (c, d, e, a, b, 8); ! 68: R0 (b, c, d, e, a, 9); ! 69: R0 (a, b, c, d, e, 10); ! 70: R0 (e, a, b, c, d, 11); ! 71: R0 (d, e, a, b, c, 12); ! 72: R0 (c, d, e, a, b, 13); ! 73: R0 (b, c, d, e, a, 14); ! 74: R0 (a, b, c, d, e, 15); ! 75: R1 (e, a, b, c, d, 16); ! 76: R1 (d, e, a, b, c, 17); ! 77: R1 (c, d, e, a, b, 18); ! 78: R1 (b, c, d, e, a, 19); ! 79: R2 (a, b, c, d, e, 20); ! 80: R2 (e, a, b, c, d, 21); ! 81: R2 (d, e, a, b, c, 22); ! 82: R2 (c, d, e, a, b, 23); ! 83: R2 (b, c, d, e, a, 24); ! 84: R2 (a, b, c, d, e, 25); ! 85: R2 (e, a, b, c, d, 26); ! 86: R2 (d, e, a, b, c, 27); ! 87: R2 (c, d, e, a, b, 28); ! 88: R2 (b, c, d, e, a, 29); ! 89: R2 (a, b, c, d, e, 30); ! 90: R2 (e, a, b, c, d, 31); ! 91: R2 (d, e, a, b, c, 32); ! 92: R2 (c, d, e, a, b, 33); ! 93: R2 (b, c, d, e, a, 34); ! 94: R2 (a, b, c, d, e, 35); ! 95: R2 (e, a, b, c, d, 36); ! 96: R2 (d, e, a, b, c, 37); ! 97: R2 (c, d, e, a, b, 38); ! 98: R2 (b, c, d, e, a, 39); ! 99: R3 (a, b, c, d, e, 40); ! 100: R3 (e, a, b, c, d, 41); ! 101: R3 (d, e, a, b, c, 42); ! 102: R3 (c, d, e, a, b, 43); ! 103: R3 (b, c, d, e, a, 44); ! 104: R3 (a, b, c, d, e, 45); ! 105: R3 (e, a, b, c, d, 46); ! 106: R3 (d, e, a, b, c, 47); ! 107: R3 (c, d, e, a, b, 48); ! 108: R3 (b, c, d, e, a, 49); ! 109: R3 (a, b, c, d, e, 50); ! 110: R3 (e, a, b, c, d, 51); ! 111: R3 (d, e, a, b, c, 52); ! 112: R3 (c, d, e, a, b, 53); ! 113: R3 (b, c, d, e, a, 54); ! 114: R3 (a, b, c, d, e, 55); ! 115: R3 (e, a, b, c, d, 56); ! 116: R3 (d, e, a, b, c, 57); ! 117: R3 (c, d, e, a, b, 58); ! 118: R3 (b, c, d, e, a, 59); ! 119: R4 (a, b, c, d, e, 60); ! 120: R4 (e, a, b, c, d, 61); ! 121: R4 (d, e, a, b, c, 62); ! 122: R4 (c, d, e, a, b, 63); ! 123: R4 (b, c, d, e, a, 64); ! 124: R4 (a, b, c, d, e, 65); ! 125: R4 (e, a, b, c, d, 66); ! 126: R4 (d, e, a, b, c, 67); ! 127: R4 (c, d, e, a, b, 68); ! 128: R4 (b, c, d, e, a, 69); ! 129: R4 (a, b, c, d, e, 70); ! 130: R4 (e, a, b, c, d, 71); ! 131: R4 (d, e, a, b, c, 72); ! 132: R4 (c, d, e, a, b, 73); ! 133: R4 (b, c, d, e, a, 74); ! 134: R4 (a, b, c, d, e, 75); ! 135: R4 (e, a, b, c, d, 76); ! 136: R4 (d, e, a, b, c, 77); ! 137: R4 (c, d, e, a, b, 78); ! 138: R4 (b, c, d, e, a, 79); ! 139: /* Add the working vars back into context.state[] */ ! 140: state[0] += a; ! 141: state[1] += b; ! 142: state[2] += c; ! 143: state[3] += d; ! 144: state[4] += e; ! 145: /* Wipe variables */ ! 146: a = b = c = d = e = 0; ! 147: } ! 148: ! 149: /* SHA1Init - Initialize new context */ ! 150: ! 151: void ! 152: _cdecl SHA1Init (SHA1_CTX * context) ! 153: { ! 154: /* SHA1 initialization constants */ ! 155: context->state[0] = 0x67452301; ! 156: context->state[1] = 0xEFCDAB89; ! 157: context->state[2] = 0x98BADCFE; ! 158: context->state[3] = 0x10325476; ! 159: context->state[4] = 0xC3D2E1F0; ! 160: context->count[0] = context->count[1] = 0; ! 161: } ! 162: ! 163: ! 164: /* Run your data through this. */ ! 165: ! 166: void ! 167: _cdecl SHA1Update (SHA1_CTX * context, unsigned char *data, unsigned int len) ! 168: { ! 169: unsigned int i, j; ! 170: ! 171: j = (context->count[0] >> 3) & 63; ! 172: if ((context->count[0] += len << 3) < (len << 3)) ! 173: context->count[1]++; ! 174: context->count[1] += (len >> 29); ! 175: if ((j + len) > 63) ! 176: { ! 177: memcpy (&context->buffer[j], data, (i = 64 - j)); ! 178: SHA1TRANSFORM (context->state, context->buffer); ! 179: for (; i + 63 < len; i += 64) ! 180: { ! 181: SHA1TRANSFORM (context->state, &data[i]); ! 182: } ! 183: j = 0; ! 184: } ! 185: else ! 186: i = 0; ! 187: memcpy (&context->buffer[j], &data[i], len - i); ! 188: } ! 189: ! 190: ! 191: /* Add padding and return the message digest. */ ! 192: ! 193: void ! 194: _cdecl SHA1Final (unsigned char digest[20], SHA1_CTX * context) ! 195: { ! 196: unsigned long i, j; ! 197: unsigned char finalcount[8]; ! 198: ! 199: for (i = 0; i < 8; i++) ! 200: { ! 201: finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] ! 202: >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ ! 203: } ! 204: SHA1Update (context, (unsigned char *) "\200", 1); ! 205: while ((context->count[0] & 504) != 448) ! 206: { ! 207: SHA1Update (context, (unsigned char *) "\0", 1); ! 208: } ! 209: SHA1Update (context, finalcount, 8); /* Should cause a SHA1Transform() */ ! 210: for (i = 0; i < 20; i++) ! 211: { ! 212: digest[i] = (unsigned char) ! 213: ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); ! 214: } ! 215: ! 216: /* Wipe variables */ ! 217: i = j = 0; ! 218: memset (context->buffer, 0, 64); ! 219: memset (context->state, 0, 20); ! 220: memset (context->count, 0, 8); ! 221: memset (&finalcount, 0, 8); ! 222: ! 223: SHA1TRANSFORM (context->state, context->buffer); ! 224: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.