|
WizardsToolkit
1.0.7
|
00001 /* 00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00003 % % 00004 % % 00005 % M M DDDD 55555 % 00006 % MM MM D D 5 % 00007 % M M M D D 55555 % 00008 % M M D D 5 % 00009 % M M DDDD 55555 % 00010 % % 00011 % % 00012 % Wizard's Toolkit Message Digest Algorithm-5 Methods % 00013 % % 00014 % Software Design % 00015 % John Cristy % 00016 % March 2003 % 00017 % % 00018 % % 00019 % Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization % 00020 % dedicated to making software imaging solutions freely available. % 00021 % % 00022 % You may not use this file except in compliance with the License. You may % 00023 % obtain a copy of the License at % 00024 % % 00025 % http://www.wizards-toolkit.org/script/license.php % 00026 % % 00027 % Unless required by applicable law or agreed to in writing, software % 00028 % distributed under the License is distributed on an "AS IS" BASIS, % 00029 % WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. % 00030 % See the License for the specific language governing permissions and % 00031 % limitations under the License. % 00032 % % 00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00034 % 00035 % 00036 */ 00037 00038 /* 00039 Include declarations. 00040 */ 00041 #include "wizard/studio.h" 00042 #include "wizard/exception.h" 00043 #include "wizard/exception-private.h" 00044 #include "wizard/memory_.h" 00045 #include "wizard/md5.h" 00046 00047 /* 00048 Define declarations. 00049 */ 00050 #define MD5Blocksize 64 00051 #define MD5Digestsize 16 00052 00053 /* 00054 Typedef declarations. 00055 */ 00056 struct _MD5Info 00057 { 00058 unsigned int 00059 digestsize, 00060 blocksize; 00061 00062 StringInfo 00063 *digest, 00064 *message; 00065 00066 unsigned int 00067 *accumulator, 00068 low_order, 00069 high_order; 00070 00071 time_t 00072 timestamp; 00073 00074 size_t 00075 signature; 00076 }; 00077 00078 /* 00079 Forward declaraction. 00080 */ 00081 static void 00082 TransformMD5(MD5Info *,unsigned int *); 00083 00084 /* 00085 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00086 % % 00087 % % 00088 % % 00089 % A c q u i r e M D 5 I n f o % 00090 % % 00091 % % 00092 % % 00093 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00094 % 00095 % AcquireMD5Info() allocate the MD5Info structure. 00096 % 00097 % The format of the AcquireMD5Info method is: 00098 % 00099 % MD5Info *AcquireMD5Info(void) 00100 % 00101 */ 00102 WizardExport MD5Info *AcquireMD5Info(void) 00103 { 00104 MD5Info 00105 *md5_info; 00106 00107 md5_info=(MD5Info *) AcquireWizardMemory(sizeof(*md5_info)); 00108 if (md5_info == (MD5Info *) NULL) 00109 ThrowWizardFatalError(HashDomain,MemoryError); 00110 (void) ResetWizardMemory(md5_info,0,sizeof(*md5_info)); 00111 md5_info->digestsize=MD5Digestsize; 00112 md5_info->blocksize=MD5Blocksize; 00113 md5_info->digest=AcquireStringInfo(MD5Digestsize); 00114 md5_info->message=AcquireStringInfo(MD5Blocksize); 00115 md5_info->accumulator=(unsigned int *) AcquireQuantumMemory(4UL, 00116 sizeof(*md5_info->accumulator)); 00117 if (md5_info->accumulator == (unsigned int *) NULL) 00118 ThrowWizardFatalError(HashDomain,MemoryError); 00119 md5_info->timestamp=time((time_t *) NULL); 00120 md5_info->signature=WizardSignature; 00121 return(md5_info); 00122 } 00123 00124 /* 00125 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00126 % % 00127 % % 00128 % % 00129 % D e s t r o y M D 5 I n f o % 00130 % % 00131 % % 00132 % % 00133 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00134 % 00135 % DestroyMD5Info() zeros memory associated with the MD5Info structure. 00136 % 00137 % The format of the DestroyMD5Info method is: 00138 % 00139 % MD5Info *DestroyMD5Info(MD5Info *md5_info) 00140 % 00141 % A description of each parameter follows: 00142 % 00143 % o md5_info: The cipher md5_info. 00144 % 00145 */ 00146 WizardExport MD5Info *DestroyMD5Info(MD5Info *md5_info) 00147 { 00148 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"..."); 00149 assert(md5_info != (MD5Info *) NULL); 00150 assert(md5_info->signature == WizardSignature); 00151 if (md5_info->accumulator != (unsigned int *) NULL) 00152 md5_info->accumulator=(unsigned int *) 00153 RelinquishWizardMemory(md5_info->accumulator); 00154 if (md5_info->message != (StringInfo *) NULL) 00155 md5_info->message=DestroyStringInfo(md5_info->message); 00156 if (md5_info->digest != (StringInfo *) NULL) 00157 md5_info->digest=DestroyStringInfo(md5_info->digest); 00158 md5_info->signature=(~WizardSignature); 00159 md5_info=(MD5Info *) RelinquishWizardMemory(md5_info); 00160 return(md5_info); 00161 } 00162 00163 /* 00164 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00165 % % 00166 % % 00167 % % 00168 % F i n a l i z e M D 5 % 00169 % % 00170 % % 00171 % % 00172 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00173 % 00174 % FinalizeMD5() finalizes the MD5 message digest computation. 00175 % 00176 % The format of the FinalizeMD5 method is: 00177 % 00178 % void FinalizeMD5(MD5Info *md5_info) 00179 % 00180 % A description of each parameter follows: 00181 % 00182 % o md5_info: The address of a structure of type MD5Info. 00183 % 00184 % 00185 */ 00186 WizardExport void FinalizeMD5(MD5Info *md5_info) 00187 { 00188 ssize_t 00189 number_bytes; 00190 00191 register ssize_t 00192 i; 00193 00194 register unsigned char 00195 *p; 00196 00197 StringInfo 00198 *pad; 00199 00200 unsigned char 00201 *datum; 00202 00203 unsigned int 00204 message[16]; 00205 00206 /* 00207 Save number of bits. 00208 */ 00209 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"..."); 00210 assert(md5_info != (MD5Info *) NULL); 00211 assert(md5_info->signature == WizardSignature); 00212 message[14]=md5_info->low_order; 00213 message[15]=md5_info->high_order; 00214 /* 00215 Final number of bytes mod 64. 00216 */ 00217 number_bytes=(ssize_t) ((md5_info->low_order >> 3) & 0x3F); 00218 /* 00219 Pad message to 56 mod 64. 00220 */ 00221 pad=AcquireStringInfo((size_t) ((number_bytes < 56) ? (56-number_bytes) : 00222 (120-number_bytes))); 00223 datum=GetStringInfoDatum(pad); 00224 datum[0]=(unsigned char) 0x80; 00225 for (i=1; i < (ssize_t) GetStringInfoLength(pad); i++) 00226 datum[i]=(unsigned char) 0x0; 00227 UpdateMD5(md5_info,pad); 00228 pad=DestroyStringInfo(pad); 00229 /* 00230 Append length in bits and transform. 00231 */ 00232 p=GetStringInfoDatum(md5_info->message); 00233 for (i=0; i < 14; i++) 00234 { 00235 message[i]=(unsigned int) (*p++); 00236 message[i]|=((unsigned int) (*p++)) << 8; 00237 message[i]|=((unsigned int) (*p++)) << 16; 00238 message[i]|=((unsigned int) (*p++)) << 24; 00239 } 00240 TransformMD5(md5_info,message); 00241 /* 00242 Store message in digest. 00243 */ 00244 p=GetStringInfoDatum(md5_info->digest); 00245 for (i=0; i < (MD5Digestsize/4); i++) 00246 { 00247 *p++=(unsigned char) (md5_info->accumulator[i] & 0xff); 00248 *p++=(unsigned char) ((md5_info->accumulator[i] >> 8) & 0xff); 00249 *p++=(unsigned char) ((md5_info->accumulator[i] >> 16) & 0xff); 00250 *p++=(unsigned char) ((md5_info->accumulator[i] >> 24) & 0xff); 00251 } 00252 /* 00253 Reset working registers. 00254 */ 00255 number_bytes=0; 00256 (void) ResetWizardMemory(message,0,sizeof(message)); 00257 } 00258 00259 /* 00260 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00261 % % 00262 % % 00263 % % 00264 % G e t M D 5 B l o c k s i z e % 00265 % % 00266 % % 00267 % % 00268 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00269 % 00270 % GetMD5Blocksize() returns the MD5 blocksize. 00271 % 00272 % The format of the GetMD5Blocksize method is: 00273 % 00274 % unsigned int *GetMD5Blocksize(const MD5Info *md5_info) 00275 % 00276 % A description of each parameter follows: 00277 % 00278 % o md5_info: The md5 info. 00279 % 00280 */ 00281 WizardExport unsigned int GetMD5Blocksize(const MD5Info *md5_info) 00282 { 00283 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"..."); 00284 WizardAssert(CipherDomain,md5_info != (MD5Info *) NULL); 00285 WizardAssert(CipherDomain,md5_info->signature == WizardSignature); 00286 return(md5_info->blocksize); 00287 } 00288 00289 /* 00290 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00291 % % 00292 % % 00293 % % 00294 % G e t M D 5 D i g e s t % 00295 % % 00296 % % 00297 % % 00298 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00299 % 00300 % GetMD5Digest() returns the MD5 digest. 00301 % 00302 % The format of the GetMD5Digest method is: 00303 % 00304 % const StringInfo *GetMD5Digest(const MD5Info *md5_info) 00305 % 00306 % A description of each parameter follows: 00307 % 00308 % o md5_info: The md5 info. 00309 % 00310 */ 00311 WizardExport const StringInfo *GetMD5Digest(const MD5Info *md5_info) 00312 { 00313 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"..."); 00314 WizardAssert(HashDomain,md5_info != (MD5Info *) NULL); 00315 WizardAssert(HashDomain,md5_info->signature == WizardSignature); 00316 return(md5_info->digest); 00317 } 00318 00319 /* 00320 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00321 % % 00322 % % 00323 % % 00324 % G e t M D 5 D i g e s t s i z e % 00325 % % 00326 % % 00327 % % 00328 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00329 % 00330 % GetMD5Digestsize() returns the MD5 digest size. 00331 % 00332 % The format of the GetMD5Digestsize method is: 00333 % 00334 % unsigned int *GetMD5Digestsize(const MD5Info *md5_info) 00335 % 00336 % A description of each parameter follows: 00337 % 00338 % o md5_info: The md5 info. 00339 % 00340 */ 00341 WizardExport unsigned int GetMD5Digestsize(const MD5Info *md5_info) 00342 { 00343 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"..."); 00344 WizardAssert(CipherDomain,md5_info != (MD5Info *) NULL); 00345 WizardAssert(CipherDomain,md5_info->signature == WizardSignature); 00346 return(md5_info->digestsize); 00347 } 00348 00349 /* 00350 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00351 % % 00352 % % 00353 % % 00354 % I n i t i a l i z e M D 5 % 00355 % % 00356 % % 00357 % % 00358 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00359 % 00360 % IntializeMD5() intializes the MD5 digest. 00361 % 00362 % The format of the InitializeMD5 method is: 00363 % 00364 % void InitializeMD5(md5_info) 00365 % 00366 % A description of each parameter follows: 00367 % 00368 % o md5_info: The address of a structure of type MD5Info. 00369 % 00370 % 00371 */ 00372 WizardExport void InitializeMD5(MD5Info *md5_info) 00373 { 00374 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"..."); 00375 assert(md5_info != (MD5Info *) NULL); 00376 assert(md5_info->signature == WizardSignature); 00377 md5_info->low_order=(unsigned int) 0; 00378 md5_info->high_order=(unsigned int) 0; 00379 /* 00380 Load magic initialization constants. 00381 */ 00382 md5_info->accumulator[0]=(unsigned int) 0x67452301; 00383 md5_info->accumulator[1]=(unsigned int) 0xefcdab89; 00384 md5_info->accumulator[2]=(unsigned int) 0x98badcfe; 00385 md5_info->accumulator[3]=(unsigned int) 0x10325476; 00386 } 00387 00388 /* 00389 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00390 % % 00391 % % 00392 % % 00393 % T r a n s f o r m M D 5 % 00394 % % 00395 % % 00396 % % 00397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00398 % 00399 % TransformMD5() transforms the MD5 message digest. 00400 % 00401 % The format of the TransformMD5 method is: 00402 % 00403 % TransformMD5(MD5Info *md5_info) 00404 % 00405 % A description of each parameter follows: 00406 % 00407 % o md5_info: The address of a structure of type MD5Info. 00408 % 00409 % 00410 */ 00411 00412 static inline unsigned int F(unsigned int x,unsigned int y,unsigned int z) 00413 { 00414 return((x & y) | (~x & z)); 00415 } 00416 00417 static inline unsigned int G(unsigned int x,unsigned int y,unsigned int z) 00418 { 00419 return((x & z) | (y & ~z)); 00420 } 00421 00422 static inline unsigned int H(unsigned int x,unsigned int y,unsigned int z) 00423 { 00424 return(x ^ y ^ z); 00425 } 00426 00427 static inline unsigned int I(unsigned int x,unsigned int y,unsigned int z) 00428 { 00429 return(y ^ (x | ~z)); 00430 } 00431 00432 static inline unsigned int Trunc32(unsigned int x) 00433 { 00434 return((unsigned int) (x & 0xffffffffUL)); 00435 } 00436 00437 static inline unsigned int RotateLeft(unsigned int x,unsigned int n) 00438 { 00439 return(Trunc32((x << n) | (x >> (32-n)))); 00440 } 00441 00442 static void TransformMD5(MD5Info *md5_info,unsigned int *message) 00443 { 00444 register ssize_t 00445 i; 00446 00447 register unsigned int 00448 j; 00449 00450 register const unsigned int 00451 *p; 00452 00453 static const unsigned int 00454 K[64]= 00455 { 00456 0xd76aa478U, 0xe8c7b756U, 0x242070dbU, 0xc1bdceeeU, 0xf57c0fafU, 00457 0x4787c62aU, 0xa8304613U, 0xfd469501U, 0x698098d8U, 0x8b44f7afU, 00458 0xffff5bb1U, 0x895cd7beU, 0x6b901122U, 0xfd987193U, 0xa679438eU, 00459 0x49b40821U, 0xf61e2562U, 0xc040b340U, 0x265e5a51U, 0xe9b6c7aaU, 00460 0xd62f105dU, 0x02441453U, 0xd8a1e681U, 0xe7d3fbc8U, 0x21e1cde6U, 00461 0xc33707d6U, 0xf4d50d87U, 0x455a14edU, 0xa9e3e905U, 0xfcefa3f8U, 00462 0x676f02d9U, 0x8d2a4c8aU, 0xfffa3942U, 0x8771f681U, 0x6d9d6122U, 00463 0xfde5380cU, 0xa4beea44U, 0x4bdecfa9U, 0xf6bb4b60U, 0xbebfbc70U, 00464 0x289b7ec6U, 0xeaa127faU, 0xd4ef3085U, 0x04881d05U, 0xd9d4d039U, 00465 0xe6db99e5U, 0x1fa27cf8U, 0xc4ac5665U, 0xf4292244U, 0x432aff97U, 00466 0xab9423a7U, 0xfc93a039U, 0x655b59c3U, 0x8f0ccc92U, 0xffeff47dU, 00467 0x85845dd1U, 0x6fa87e4fU, 0xfe2ce6e0U, 0xa3014314U, 0x4e0811a1U, 00468 0xf7537e82U, 0xbd3af235U, 0x2ad7d2bbU, 0xeb86d391U, 00469 }; /* 4294967296*abs(sin(i)), i in radians */ 00470 00471 unsigned int 00472 A, 00473 B, 00474 C, 00475 D; 00476 /* 00477 Copy accumulator to registers 00478 */ 00479 A=md5_info->accumulator[0]; 00480 B=md5_info->accumulator[1]; 00481 C=md5_info->accumulator[2]; 00482 D=md5_info->accumulator[3]; 00483 /* 00484 a=b+((a+F(b,c,d)+X[k]+t) <<< s). 00485 */ 00486 p=K; 00487 j=0; 00488 for (i=0; i < 4; i++) 00489 { 00490 A+=F(B,C,D)+message[j & 0x0f]+(*p++); 00491 A=RotateLeft(A,7)+B; 00492 j++; 00493 D+=F(A,B,C)+message[j & 0x0f]+(*p++); 00494 D=RotateLeft(D,12)+A; 00495 j++; 00496 C+=F(D,A,B)+message[j & 0x0f]+(*p++); 00497 C=RotateLeft(C,17)+D; 00498 j++; 00499 B+=F(C,D,A)+message[j & 0x0f]+(*p++); 00500 B=RotateLeft(B,22)+C; 00501 j++; 00502 } 00503 /* 00504 a=b+((a+G(b,c,d)+X[k]+t) <<< s). 00505 */ 00506 j=1; 00507 for (i=0; i < 4; i++) 00508 { 00509 A+=G(B,C,D)+message[j & 0x0f]+(*p++); 00510 A=RotateLeft(A,5)+B; 00511 j+=5; 00512 D+=G(A,B,C)+message[j & 0x0f]+(*p++); 00513 D=RotateLeft(D,9)+A; 00514 j+=5; 00515 C+=G(D,A,B)+message[j & 0x0f]+(*p++); 00516 C=RotateLeft(C,14)+D; 00517 j+=5; 00518 B+=G(C,D,A)+message[j & 0x0f]+(*p++); 00519 B=RotateLeft(B,20)+C; 00520 j+=5; 00521 } 00522 /* 00523 a=b+((a+H(b,c,d)+X[k]+t) <<< s). 00524 */ 00525 j=5; 00526 for (i=0; i < 4; i++) 00527 { 00528 A+=H(B,C,D)+message[j & 0x0f]+(*p++); 00529 A=RotateLeft(A,4)+B; 00530 j+=3; 00531 D+=H(A,B,C)+message[j & 0x0f]+(*p++); 00532 D=RotateLeft(D,11)+A; 00533 j+=3; 00534 C+=H(D,A,B)+message[j & 0x0f]+(*p++); 00535 C=RotateLeft(C,16)+D; 00536 j+=3; 00537 B+=H(C,D,A)+message[j & 0x0f]+(*p++); 00538 B=RotateLeft(B,23)+C; 00539 j+=3; 00540 } 00541 /* 00542 a=b+((a+I(b,c,d)+X[k]+t) <<< s). 00543 */ 00544 j=0; 00545 for (i=0; i < 4; i++) 00546 { 00547 A+=I(B,C,D)+message[j & 0x0f]+(*p++); 00548 A=RotateLeft(A,6)+B; 00549 j+=7; 00550 D+=I(A,B,C)+message[j & 0x0f]+(*p++); 00551 D=RotateLeft(D,10)+A; 00552 j+=7; 00553 C+=I(D,A,B)+message[j & 0x0f]+(*p++); 00554 C=RotateLeft(C,15)+D; 00555 j+=7; 00556 B+=I(C,D,A)+message[j & 0x0f]+(*p++); 00557 B=RotateLeft(B,21)+C; 00558 j+=7; 00559 } 00560 /* 00561 Add registers back to accumulator. 00562 */ 00563 md5_info->accumulator[0]=Trunc32(md5_info->accumulator[0]+A); 00564 md5_info->accumulator[1]=Trunc32(md5_info->accumulator[1]+B); 00565 md5_info->accumulator[2]=Trunc32(md5_info->accumulator[2]+C); 00566 md5_info->accumulator[3]=Trunc32(md5_info->accumulator[3]+D); 00567 /* 00568 Reset working registers. 00569 */ 00570 A=0; 00571 B=0; 00572 C=0; 00573 D=0; 00574 } 00575 00576 /* 00577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00578 % % 00579 % % 00580 % % 00581 % U p d a t e M D 5 % 00582 % % 00583 % % 00584 % % 00585 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% 00586 % 00587 % UpdateMD5() updates the MD5 message digest 00588 % 00589 % The format of the UpdateMD5 method is: 00590 % 00591 % UpdateMD5(MD5Info *md5_info,const unsigned char *message) 00592 % 00593 % A description of each parameter follows: 00594 % 00595 % o md5_info: The address of a structure of type MD5Info. 00596 % 00597 */ 00598 WizardExport void UpdateMD5(MD5Info *md5_info,const StringInfo *message) 00599 { 00600 register unsigned char 00601 *p; 00602 00603 register ssize_t 00604 i, 00605 j; 00606 00607 unsigned char 00608 *datum; 00609 00610 unsigned int 00611 buffer[16], 00612 number_bits, 00613 number_bytes; 00614 00615 /* 00616 Update the MD5 accumulator. 00617 */ 00618 assert(md5_info != (MD5Info *) NULL); 00619 assert(md5_info->signature == WizardSignature); 00620 number_bytes=(unsigned int) ((md5_info->low_order >> 3) & 0x3F); 00621 number_bits=(unsigned int) (md5_info->low_order+(GetStringInfoLength(message) 00622 << 3)); 00623 if ((number_bits & 0xffffffff) < md5_info->low_order) 00624 md5_info->high_order++; 00625 md5_info->low_order+=(unsigned int) (GetStringInfoLength(message) << 3); 00626 md5_info->high_order+=(unsigned int) (GetStringInfoLength(message) >> 29); 00627 datum=GetStringInfoDatum(message); 00628 for (i=0; i < (ssize_t) GetStringInfoLength(message); i++) 00629 { 00630 p=GetStringInfoDatum(md5_info->message); 00631 p[number_bytes++]=datum[i]; 00632 if (number_bytes != 0x40) 00633 continue; 00634 for (j=0; j < 16; j++) 00635 { 00636 buffer[j]=(unsigned int) (*p++); 00637 buffer[j]|=((unsigned int) (*p++)) << 8; 00638 buffer[j]|=((unsigned int) (*p++)) << 16; 00639 buffer[j]|=((unsigned int) (*p++)) << 24; 00640 } 00641 TransformMD5(md5_info,buffer); 00642 number_bytes=0; 00643 } 00644 /* 00645 Reset working registers. 00646 */ 00647 number_bits=0; 00648 number_bytes=0; 00649 (void) ResetWizardMemory(buffer,0,sizeof(buffer)); 00650 }