sha1.c (3941B)
1 /********************************************************************* 2 * Filename: sha1.c 3 * Author: Brad Conte (brad AT bradconte.com) 4 * Copyright: 5 * Disclaimer: This code is presented "as is" without any guarantees. 6 * Details: Implementation of the SHA1 hashing algorithm. 7 Algorithm specification can be found here: 8 * http://csrc.nist.gov/publications/fips/fips180-2/fips180-2withchangenotice.pdf 9 This implementation uses little endian byte order. 10 *********************************************************************/ 11 12 /*************************** HEADER FILES ***************************/ 13 #include <stdlib.h> 14 #include <memory.h> 15 #include "sha1.h" 16 17 /****************************** MACROS ******************************/ 18 #define ROTLEFT(a, b) ((a << b) | (a >> (32 - b))) 19 20 /*********************** FUNCTION DEFINITIONS ***********************/ 21 void sha1_transform(SHA1_CTX *ctx, const BYTE data[]) 22 { 23 WORD a, b, c, d, e, i, j, t, m[80]; 24 25 for (i = 0, j = 0; i < 16; ++i, j += 4) 26 m[i] = (data[j] << 24) + (data[j + 1] << 16) + (data[j + 2] << 8) + (data[j + 3]); 27 for ( ; i < 80; ++i) { 28 m[i] = (m[i - 3] ^ m[i - 8] ^ m[i - 14] ^ m[i - 16]); 29 m[i] = (m[i] << 1) | (m[i] >> 31); 30 } 31 32 a = ctx->state[0]; 33 b = ctx->state[1]; 34 c = ctx->state[2]; 35 d = ctx->state[3]; 36 e = ctx->state[4]; 37 38 for (i = 0; i < 20; ++i) { 39 t = ROTLEFT(a, 5) + ((b & c) ^ (~b & d)) + e + ctx->k[0] + m[i]; 40 e = d; 41 d = c; 42 c = ROTLEFT(b, 30); 43 b = a; 44 a = t; 45 } 46 for ( ; i < 40; ++i) { 47 t = ROTLEFT(a, 5) + (b ^ c ^ d) + e + ctx->k[1] + m[i]; 48 e = d; 49 d = c; 50 c = ROTLEFT(b, 30); 51 b = a; 52 a = t; 53 } 54 for ( ; i < 60; ++i) { 55 t = ROTLEFT(a, 5) + ((b & c) ^ (b & d) ^ (c & d)) + e + ctx->k[2] + m[i]; 56 e = d; 57 d = c; 58 c = ROTLEFT(b, 30); 59 b = a; 60 a = t; 61 } 62 for ( ; i < 80; ++i) { 63 t = ROTLEFT(a, 5) + (b ^ c ^ d) + e + ctx->k[3] + m[i]; 64 e = d; 65 d = c; 66 c = ROTLEFT(b, 30); 67 b = a; 68 a = t; 69 } 70 71 ctx->state[0] += a; 72 ctx->state[1] += b; 73 ctx->state[2] += c; 74 ctx->state[3] += d; 75 ctx->state[4] += e; 76 } 77 78 void sha1_init(SHA1_CTX *ctx) 79 { 80 ctx->datalen = 0; 81 ctx->bitlen = 0; 82 ctx->state[0] = 0x67452301; 83 ctx->state[1] = 0xEFCDAB89; 84 ctx->state[2] = 0x98BADCFE; 85 ctx->state[3] = 0x10325476; 86 ctx->state[4] = 0xc3d2e1f0; 87 ctx->k[0] = 0x5a827999; 88 ctx->k[1] = 0x6ed9eba1; 89 ctx->k[2] = 0x8f1bbcdc; 90 ctx->k[3] = 0xca62c1d6; 91 } 92 93 void sha1_update(SHA1_CTX *ctx, const BYTE data[], size_t len) 94 { 95 size_t i; 96 97 for (i = 0; i < len; ++i) { 98 ctx->data[ctx->datalen] = data[i]; 99 ctx->datalen++; 100 if (ctx->datalen == 64) { 101 sha1_transform(ctx, ctx->data); 102 ctx->bitlen += 512; 103 ctx->datalen = 0; 104 } 105 } 106 } 107 108 void sha1_final(SHA1_CTX *ctx, BYTE hash[]) 109 { 110 WORD i; 111 112 i = ctx->datalen; 113 114 // Pad whatever data is left in the buffer. 115 if (ctx->datalen < 56) { 116 ctx->data[i++] = 0x80; 117 while (i < 56) 118 ctx->data[i++] = 0x00; 119 } 120 else { 121 ctx->data[i++] = 0x80; 122 while (i < 64) 123 ctx->data[i++] = 0x00; 124 sha1_transform(ctx, ctx->data); 125 memset(ctx->data, 0, 56); 126 } 127 128 // Append to the padding the total message's length in bits and transform. 129 ctx->bitlen += ctx->datalen * 8; 130 ctx->data[63] = ctx->bitlen; 131 ctx->data[62] = ctx->bitlen >> 8; 132 ctx->data[61] = ctx->bitlen >> 16; 133 ctx->data[60] = ctx->bitlen >> 24; 134 ctx->data[59] = ctx->bitlen >> 32; 135 ctx->data[58] = ctx->bitlen >> 40; 136 ctx->data[57] = ctx->bitlen >> 48; 137 ctx->data[56] = ctx->bitlen >> 56; 138 sha1_transform(ctx, ctx->data); 139 140 // Since this implementation uses little endian byte ordering and MD uses big endian, 141 // reverse all the bytes when copying the final state to the output hash. 142 for (i = 0; i < 4; ++i) { 143 hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff; 144 hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff; 145 hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff; 146 hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff; 147 hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff; 148 } 149 }