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 #include "asterisk.h"
00064 #include "asterisk/sha1.h"
00065
00066
00067 #define SHA1CircularShift(bits,word) \
00068 (((word) << (bits)) | ((word) >> (32-(bits))))
00069
00070
00071 void SHA1PadMessage(SHA1Context *);
00072 void SHA1ProcessMessageBlock(SHA1Context *);
00073
00074
00075
00076
00077
00078
00079
00080
00081 int SHA1Reset(SHA1Context *context)
00082 {
00083 if (!context) {
00084 return shaNull;
00085 }
00086
00087 context->Length_Low = 0;
00088 context->Length_High = 0;
00089 context->Message_Block_Index = 0;
00090
00091 context->Intermediate_Hash[0] = 0x67452301;
00092 context->Intermediate_Hash[1] = 0xEFCDAB89;
00093 context->Intermediate_Hash[2] = 0x98BADCFE;
00094 context->Intermediate_Hash[3] = 0x10325476;
00095 context->Intermediate_Hash[4] = 0xC3D2E1F0;
00096
00097 context->Computed = 0;
00098 context->Corrupted = 0;
00099
00100 return shaSuccess;
00101 }
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 int SHA1Result( SHA1Context *context,
00114 uint8_t Message_Digest[SHA1HashSize])
00115 {
00116 int i;
00117
00118 if (!context || !Message_Digest) {
00119 return shaNull;
00120 }
00121
00122 if (context->Corrupted) {
00123 return context->Corrupted;
00124 }
00125
00126 if (!context->Computed) {
00127 SHA1PadMessage(context);
00128 for (i = 0; i < 64; ++i) {
00129
00130 context->Message_Block[i] = 0;
00131 }
00132 context->Length_Low = 0;
00133 context->Length_High = 0;
00134 context->Computed = 1;
00135 }
00136
00137 for (i = 0; i < SHA1HashSize; ++i) {
00138 Message_Digest[i] = context->Intermediate_Hash[i >> 2] >> 8 * ( 3 - ( i & 0x03 ) );
00139 }
00140
00141 return shaSuccess;
00142 }
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154 int SHA1Input(SHA1Context *context, const uint8_t *message_array, unsigned length)
00155 {
00156 if (!length) {
00157 return shaSuccess;
00158 }
00159
00160 if (!context || !message_array) {
00161 return shaNull;
00162 }
00163
00164 if (context->Computed) {
00165 context->Corrupted = shaStateError;
00166 return shaStateError;
00167 }
00168
00169 if (context->Corrupted) {
00170 return context->Corrupted;
00171 }
00172
00173 while (length-- && !context->Corrupted) {
00174 context->Message_Block[context->Message_Block_Index++] = (*message_array & 0xFF);
00175
00176 context->Length_Low += 8;
00177 if (context->Length_Low == 0) {
00178 context->Length_High++;
00179 if (context->Length_High == 0) {
00180
00181 context->Corrupted = 1;
00182 }
00183 }
00184
00185 if (context->Message_Block_Index == 64) {
00186 SHA1ProcessMessageBlock(context);
00187 }
00188
00189 message_array++;
00190 }
00191
00192 return shaSuccess;
00193 }
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203 void SHA1ProcessMessageBlock(SHA1Context *context)
00204 {
00205 const uint32_t K[] = {
00206 0x5A827999,
00207 0x6ED9EBA1,
00208 0x8F1BBCDC,
00209 0xCA62C1D6
00210 };
00211 int t;
00212 uint32_t temp;
00213 uint32_t W[80];
00214 uint32_t A, B, C, D, E;
00215
00216
00217
00218
00219 for (t = 0; t < 16; t++) {
00220 W[t] = context->Message_Block[t * 4] << 24;
00221 W[t] |= context->Message_Block[t * 4 + 1] << 16;
00222 W[t] |= context->Message_Block[t * 4 + 2] << 8;
00223 W[t] |= context->Message_Block[t * 4 + 3];
00224 }
00225
00226 for (t = 16; t < 80; t++) {
00227 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
00228 }
00229
00230 A = context->Intermediate_Hash[0];
00231 B = context->Intermediate_Hash[1];
00232 C = context->Intermediate_Hash[2];
00233 D = context->Intermediate_Hash[3];
00234 E = context->Intermediate_Hash[4];
00235
00236 for (t = 0; t < 20; t++) {
00237 temp = SHA1CircularShift(5,A) + ((B & C) | ((~B) & D)) + E + W[t] + K[0];
00238 E = D;
00239 D = C;
00240 C = SHA1CircularShift(30,B);
00241 B = A;
00242 A = temp;
00243 }
00244
00245 for (t = 20; t < 40; t++) {
00246 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
00247 E = D;
00248 D = C;
00249 C = SHA1CircularShift(30,B);
00250 B = A;
00251 A = temp;
00252 }
00253
00254 for (t = 40; t < 60; t++) {
00255 temp = SHA1CircularShift(5,A) + ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
00256 E = D;
00257 D = C;
00258 C = SHA1CircularShift(30,B);
00259 B = A;
00260 A = temp;
00261 }
00262
00263 for (t = 60; t < 80; t++) {
00264 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
00265 E = D;
00266 D = C;
00267 C = SHA1CircularShift(30,B);
00268 B = A;
00269 A = temp;
00270 }
00271
00272 context->Intermediate_Hash[0] += A;
00273 context->Intermediate_Hash[1] += B;
00274 context->Intermediate_Hash[2] += C;
00275 context->Intermediate_Hash[3] += D;
00276 context->Intermediate_Hash[4] += E;
00277
00278 context->Message_Block_Index = 0;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 void SHA1PadMessage(SHA1Context *context)
00299 {
00300
00301
00302
00303
00304
00305
00306 if (context->Message_Block_Index > 55) {
00307 context->Message_Block[context->Message_Block_Index++] = 0x80;
00308 while (context->Message_Block_Index < 64) {
00309 context->Message_Block[context->Message_Block_Index++] = 0;
00310 }
00311
00312 SHA1ProcessMessageBlock(context);
00313
00314 while (context->Message_Block_Index < 56) {
00315 context->Message_Block[context->Message_Block_Index++] = 0;
00316 }
00317 } else {
00318 context->Message_Block[context->Message_Block_Index++] = 0x80;
00319 while (context->Message_Block_Index < 56) {
00320 context->Message_Block[context->Message_Block_Index++] = 0;
00321 }
00322 }
00323
00324
00325
00326
00327 context->Message_Block[56] = context->Length_High >> 24;
00328 context->Message_Block[57] = context->Length_High >> 16;
00329 context->Message_Block[58] = context->Length_High >> 8;
00330 context->Message_Block[59] = context->Length_High;
00331 context->Message_Block[60] = context->Length_Low >> 24;
00332 context->Message_Block[61] = context->Length_Low >> 16;
00333 context->Message_Block[62] = context->Length_Low >> 8;
00334 context->Message_Block[63] = context->Length_Low;
00335
00336 SHA1ProcessMessageBlock(context);
00337 }