md5.c

Go to the documentation of this file.
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-2010 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 *) AcquireAlignedMemory(1,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 }
Generated by  doxygen 1.6.2-20100208