00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 #include "sha1.h"
00067
00068 namespace Barry {
00069
00070 static void shaHashBlock(SHA_CTX *ctx);
00071
00072 void SHA1(const void *dataIn, int len, unsigned char *hashout)
00073 {
00074 SHA_CTX ctx;
00075 SHA1_Init(&ctx);
00076 SHA1_Update(&ctx, dataIn, len);
00077 SHA1_Final(hashout, &ctx);
00078 }
00079
00080 void SHA1_Init(SHA_CTX *ctx) {
00081 int i;
00082
00083 ctx->lenW = 0;
00084 ctx->sizeHi = ctx->sizeLo = 0;
00085
00086
00087
00088 ctx->H[0] = 0x67452301;
00089 ctx->H[1] = 0xefcdab89;
00090 ctx->H[2] = 0x98badcfe;
00091 ctx->H[3] = 0x10325476;
00092 ctx->H[4] = 0xc3d2e1f0;
00093
00094 for (i = 0; i < 80; i++)
00095 ctx->W[i] = 0;
00096 }
00097
00098
00099 void SHA1_Update(SHA_CTX *ctx, const void *_dataIn, int len) {
00100 const unsigned char *dataIn = (const unsigned char *) _dataIn;
00101 int i;
00102
00103
00104
00105 for (i = 0; i < len; i++) {
00106 ctx->W[ctx->lenW / 4] <<= 8;
00107 ctx->W[ctx->lenW / 4] |= (unsigned int)dataIn[i];
00108 if ((++ctx->lenW) % 64 == 0) {
00109 shaHashBlock(ctx);
00110 ctx->lenW = 0;
00111 }
00112 ctx->sizeLo += 8;
00113 ctx->sizeHi += (ctx->sizeLo < 8);
00114 }
00115 }
00116
00117
00118 void SHA1_Final(unsigned char hashout[20], SHA_CTX *ctx) {
00119 unsigned char pad0x80 = 0x80;
00120 unsigned char pad0x00 = 0x00;
00121 unsigned char padlen[8];
00122 int i;
00123
00124
00125
00126 padlen[0] = (unsigned char)((ctx->sizeHi >> 24) & 255);
00127 padlen[1] = (unsigned char)((ctx->sizeHi >> 16) & 255);
00128 padlen[2] = (unsigned char)((ctx->sizeHi >> 8) & 255);
00129 padlen[3] = (unsigned char)((ctx->sizeHi >> 0) & 255);
00130 padlen[4] = (unsigned char)((ctx->sizeLo >> 24) & 255);
00131 padlen[5] = (unsigned char)((ctx->sizeLo >> 16) & 255);
00132 padlen[6] = (unsigned char)((ctx->sizeLo >> 8) & 255);
00133 padlen[7] = (unsigned char)((ctx->sizeLo >> 0) & 255);
00134 SHA1_Update(ctx, &pad0x80, 1);
00135 while (ctx->lenW != 56)
00136 SHA1_Update(ctx, &pad0x00, 1);
00137 SHA1_Update(ctx, padlen, 8);
00138
00139
00140
00141 for (i = 0; i < 20; i++) {
00142 hashout[i] = (unsigned char)(ctx->H[i / 4] >> 24);
00143 ctx->H[i / 4] <<= 8;
00144 }
00145
00146
00147
00148
00149 SHA1_Init(ctx);
00150 }
00151
00152
00153 #define SHA_ROT(X,n) (((X) << (n)) | ((X) >> (32-(n))))
00154
00155 static void shaHashBlock(SHA_CTX *ctx) {
00156 int t;
00157 unsigned int A,B,C,D,E,TEMP;
00158
00159 for (t = 16; t <= 79; t++)
00160 ctx->W[t] =
00161 SHA_ROT(ctx->W[t-3] ^ ctx->W[t-8] ^ ctx->W[t-14] ^ ctx->W[t-16], 1);
00162
00163 A = ctx->H[0];
00164 B = ctx->H[1];
00165 C = ctx->H[2];
00166 D = ctx->H[3];
00167 E = ctx->H[4];
00168
00169 for (t = 0; t <= 19; t++) {
00170 TEMP = SHA_ROT(A,5) + (((C^D)&B)^D) + E + ctx->W[t] + 0x5a827999;
00171 E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
00172 }
00173 for (t = 20; t <= 39; t++) {
00174 TEMP = SHA_ROT(A,5) + (B^C^D) + E + ctx->W[t] + 0x6ed9eba1;
00175 E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
00176 }
00177 for (t = 40; t <= 59; t++) {
00178 TEMP = SHA_ROT(A,5) + ((B&C)|(D&(B|C))) + E + ctx->W[t] + 0x8f1bbcdc;
00179 E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
00180 }
00181 for (t = 60; t <= 79; t++) {
00182 TEMP = SHA_ROT(A,5) + (B^C^D) + E + ctx->W[t] + 0xca62c1d6;
00183 E = D; D = C; C = SHA_ROT(B, 30); B = A; A = TEMP;
00184 }
00185
00186 ctx->H[0] += A;
00187 ctx->H[1] += B;
00188 ctx->H[2] += C;
00189 ctx->H[3] += D;
00190 ctx->H[4] += E;
00191 }
00192
00193 }
00194