WizardsToolkit  1.0.7
sha224.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %                             SSSSS  H   H   AAA                              %
00006 %                             SS     H   H  A   A                             %
00007 %                              SSS   HHHHH  AAAAA                             %
00008 %                                SS  H   H  A   A                             %
00009 %                             SSSSS  H   H  A   A                             %
00010 %                                                                             %
00011 %                                                                             %
00012 %             Wizard's Toolkit Secure Hash Algorithm-224 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 % See http://csrc.nist.gov/cryptval/shs.htm.
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
00041 */
00042 #include "wizard/studio.h"
00043 #include "wizard/exception.h"
00044 #include "wizard/exception-private.h"
00045 #include "wizard/memory_.h"
00046 #include "wizard/sha224.h"
00047 /*
00048   Define declarations.
00049 */
00050 #define SHA224Blocksize  64
00051 #define SHA224Digestsize  28
00052 
00053 /*
00054   Typedef declarations.
00055 */
00056 struct _SHA224Info
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   size_t
00072     offset;
00073 
00074   WizardBooleanType
00075     lsb_first;
00076 
00077   time_t
00078     timestamp;
00079 
00080   size_t
00081     signature;
00082 };
00083 
00084 /*
00085   Forward declarations.
00086 */
00087 static void
00088   TransformSHA224(SHA224Info *);
00089 
00090 /*
00091 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00092 %                                                                             %
00093 %                                                                             %
00094 %                                                                             %
00095 %   A c q u i r e S H A I n f o                                               %
00096 %                                                                             %
00097 %                                                                             %
00098 %                                                                             %
00099 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00100 %
00101 %  AcquireSHA224Info() allocate the SHA224Info structure.
00102 %
00103 %  The format of the AcquireSHA224Info method is:
00104 %
00105 %      SHA224Info *AcquireSHA224Info(void)
00106 %
00107 */
00108 WizardExport SHA224Info *AcquireSHA224Info(void)
00109 {
00110   SHA224Info
00111     *sha_info;
00112 
00113   unsigned int
00114     lsb_first;
00115 
00116   sha_info=(SHA224Info *) AcquireWizardMemory(sizeof(*sha_info));
00117   if (sha_info == (SHA224Info *) NULL)
00118     ThrowWizardFatalError(HashError,MemoryError);
00119   (void) ResetWizardMemory(sha_info,0,sizeof(*sha_info));
00120   sha_info->digestsize=SHA224Digestsize;
00121   sha_info->blocksize=SHA224Blocksize;
00122   sha_info->digest=AcquireStringInfo(SHA224Digestsize);
00123   sha_info->message=AcquireStringInfo(SHA224Blocksize);
00124   sha_info->accumulator=(unsigned int *) AcquireQuantumMemory(SHA224Blocksize,
00125     sizeof(*sha_info->accumulator));
00126   if (sha_info->accumulator == (unsigned int *) NULL)
00127     ThrowWizardFatalError(HashError,MemoryError);
00128   lsb_first=1;
00129   sha_info->lsb_first=(*(char *) &lsb_first) != 0 ? WizardTrue : WizardFalse;
00130   sha_info->timestamp=time((time_t *) NULL);
00131   sha_info->signature=WizardSignature;
00132   InitializeSHA224(sha_info);
00133   return(sha_info);
00134 }
00135 
00136 /*
00137 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00138 %                                                                             %
00139 %                                                                             %
00140 %                                                                             %
00141 %   D e s t r o y S H A I n f o                                               %
00142 %                                                                             %
00143 %                                                                             %
00144 %                                                                             %
00145 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00146 %
00147 %  DestroySHA224Info() zeros memory associated with the SHA224Info structure.
00148 %
00149 %  The format of the DestroySHA224Info method is:
00150 %
00151 %      SHA224Info *DestroySHA224Info(SHA224Info *sha_info)
00152 %
00153 %  A description of each parameter follows:
00154 %
00155 %    o sha_info: The cipher sha_info.
00156 %
00157 */
00158 WizardExport SHA224Info *DestroySHA224Info(SHA224Info *sha_info)
00159 {
00160   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00161   assert(sha_info != (SHA224Info *) NULL);
00162   assert(sha_info->signature == WizardSignature);
00163   if (sha_info->accumulator != (unsigned int *) NULL)
00164     sha_info->accumulator=(unsigned int *)
00165       RelinquishWizardMemory(sha_info->accumulator);
00166   if (sha_info->message != (StringInfo *) NULL)
00167     sha_info->message=DestroyStringInfo(sha_info->message);
00168   if (sha_info->digest != (StringInfo *) NULL)
00169     sha_info->digest=DestroyStringInfo(sha_info->digest);
00170   sha_info->signature=(~WizardSignature);
00171   sha_info=(SHA224Info *) RelinquishWizardMemory(sha_info);
00172   return(sha_info);
00173 }
00174 
00175 /*
00176 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00177 %                                                                             %
00178 %                                                                             %
00179 %                                                                             %
00180 %   F i n a l i z e S H A                                                     %
00181 %                                                                             %
00182 %                                                                             %
00183 %                                                                             %
00184 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00185 %
00186 %  FinalizeSHA224() finalizes the SHA224 message accumulator computation.
00187 %
00188 %  The format of the FinalizeSHA224 method is:
00189 %
00190 %      FinalizeSHA224(SHA224Info *sha_info)
00191 %
00192 %  A description of each parameter follows:
00193 %
00194 %    o sha_info: The address of a structure of type SHA224Info.
00195 %
00196 %
00197 */
00198 WizardExport void FinalizeSHA224(SHA224Info *sha_info)
00199 {
00200   register ssize_t
00201     i;
00202 
00203   register unsigned char
00204     *q;
00205 
00206   register unsigned int
00207     *p;
00208 
00209   unsigned char
00210     *datum;
00211 
00212   unsigned int
00213     count,
00214     high_order,
00215     low_order;
00216 
00217   /*
00218     Add padding and return the message accumulator.
00219   */
00220   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00221   assert(sha_info != (SHA224Info *) NULL);
00222   assert(sha_info->signature == WizardSignature);
00223   low_order=sha_info->low_order;
00224   high_order=sha_info->high_order;
00225   count=((low_order >> 3) & 0x3f);
00226   datum=GetStringInfoDatum(sha_info->message);
00227   datum[count++]=(unsigned char) 0x80;
00228   if (count <= (unsigned int) (GetStringInfoLength(sha_info->message)-8))
00229     (void) ResetWizardMemory(datum+count,0,
00230       GetStringInfoLength(sha_info->message)-8-count);
00231   else
00232     {
00233       (void) ResetWizardMemory(datum+count,0,
00234         GetStringInfoLength(sha_info->message)-count);
00235       TransformSHA224(sha_info);
00236       (void) ResetWizardMemory(datum,0,
00237         GetStringInfoLength(sha_info->message)-8);
00238     }
00239   datum[56]=(unsigned char) (high_order >> 24);
00240   datum[57]=(unsigned char) (high_order >> 16);
00241   datum[58]=(unsigned char) (high_order >> 8);
00242   datum[59]=(unsigned char) high_order;
00243   datum[60]=(unsigned char) (low_order >> 24);
00244   datum[61]=(unsigned char) (low_order >> 16);
00245   datum[62]=(unsigned char) (low_order >> 8);
00246   datum[63]=(unsigned char) low_order;
00247   TransformSHA224(sha_info);
00248   p=sha_info->accumulator;
00249   q=GetStringInfoDatum(sha_info->digest);
00250   for (i=0; i < (SHA224Digestsize/4); i++)
00251   {
00252     *q++=(unsigned char) ((*p >> 24) & 0xff);
00253     *q++=(unsigned char) ((*p >> 16) & 0xff);
00254     *q++=(unsigned char) ((*p >> 8) & 0xff);
00255     *q++=(unsigned char) (*p & 0xff);
00256     p++;
00257   }
00258   /*
00259     Reset working registers.
00260   */
00261   count=0;
00262   high_order=0;
00263   low_order=0;
00264 }
00265 
00266 /*
00267 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00268 %                                                                             %
00269 %                                                                             %
00270 %                                                                             %
00271 %   G e t S H A 2 2 4 B l o c k s i z e                                       %
00272 %                                                                             %
00273 %                                                                             %
00274 %                                                                             %
00275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00276 %
00277 %  GetSHA224Blocksize() returns the SHA224 blocksize.
00278 %
00279 %  The format of the GetSHA224Blocksize method is:
00280 %
00281 %      unsigned int *GetSHA224Blocksize(const SHA224Info *sha224_info)
00282 %
00283 %  A description of each parameter follows:
00284 %
00285 %    o sha224_info: The sha224 info.
00286 %
00287 */
00288 WizardExport unsigned int GetSHA224Blocksize(const SHA224Info *sha224_info)
00289 {
00290   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00291   WizardAssert(CipherDomain,sha224_info != (SHA224Info *) NULL);
00292   WizardAssert(CipherDomain,sha224_info->signature == WizardSignature);
00293   return(sha224_info->blocksize);
00294 }
00295 
00296 /*
00297 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00298 %                                                                             %
00299 %                                                                             %
00300 %                                                                             %
00301 %   G e t S H A 2 2 4 D i g e s t                                             %
00302 %                                                                             %
00303 %                                                                             %
00304 %                                                                             %
00305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00306 %
00307 %  GetSHA224Digest() returns the SHA224 digest.
00308 %
00309 %  The format of the GetSHA224Digest method is:
00310 %
00311 %      const StringInfo *GetSHA224Digest(const SHA224Info *sha224_info)
00312 %
00313 %  A description of each parameter follows:
00314 %
00315 %    o sha224_info: The sha224 info.
00316 %
00317 */
00318 WizardExport const StringInfo *GetSHA224Digest(const SHA224Info *sha224_info)
00319 {
00320   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00321   WizardAssert(HashDomain,sha224_info != (SHA224Info *) NULL);
00322   WizardAssert(HashDomain,sha224_info->signature == WizardSignature);
00323   return(sha224_info->digest);
00324 }
00325 
00326 /*
00327 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00328 %                                                                             %
00329 %                                                                             %
00330 %                                                                             %
00331 %   G e t S H A 2 2 4 D i g e s t s i z e                                     %
00332 %                                                                             %
00333 %                                                                             %
00334 %                                                                             %
00335 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00336 %
00337 %  GetSHA224Digestsize() returns the SHA224 digest size.
00338 %
00339 %  The format of the GetSHA224Digestsize method is:
00340 %
00341 %      unsigned int *GetSHA224Digestsize(const SHA224Info *sha224_info)
00342 %
00343 %  A description of each parameter follows:
00344 %
00345 %    o sha224_info: The sha224 info.
00346 %
00347 */
00348 WizardExport unsigned int GetSHA224Digestsize(const SHA224Info *sha224_info)
00349 {
00350   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00351   WizardAssert(CipherDomain,sha224_info != (SHA224Info *) NULL);
00352   WizardAssert(CipherDomain,sha224_info->signature == WizardSignature);
00353   return(sha224_info->digestsize);
00354 }
00355 
00356 /*
00357 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00358 %                                                                             %
00359 %                                                                             %
00360 %                                                                             %
00361 %   I n i t i a l i z e S H A                                                 %
00362 %                                                                             %
00363 %                                                                             %
00364 %                                                                             %
00365 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00366 %
00367 %  IntializeSHA224() intializes the SHA224 accumulator.
00368 %
00369 %  The format of the DestroySHA224Info method is:
00370 %
00371 %      void InitializeSHA224Info(SHA224Info *sha_info)
00372 %
00373 %  A description of each parameter follows:
00374 %
00375 %    o sha_info: The cipher sha_info.
00376 %
00377 */
00378 WizardExport void InitializeSHA224(SHA224Info *sha_info)
00379 {
00380   (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00381   assert(sha_info != (SHA224Info *) NULL);
00382   assert(sha_info->signature == WizardSignature);
00383   sha_info->accumulator[0]=0xc1059ed8U;
00384   sha_info->accumulator[1]=0x367cd507U;
00385   sha_info->accumulator[2]=0x3070dd17U;
00386   sha_info->accumulator[3]=0xf70e5939U;
00387   sha_info->accumulator[4]=0xffc00b31U;
00388   sha_info->accumulator[5]=0x68581511U;
00389   sha_info->accumulator[6]=0x64f98fa7U;
00390   sha_info->accumulator[7]=0xbefa4fa4U;
00391   sha_info->low_order=0;
00392   sha_info->high_order=0;
00393   sha_info->offset=0;
00394 }
00395 
00396 /*
00397 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00398 %                                                                             %
00399 %                                                                             %
00400 %                                                                             %
00401 %   T r a n s f o r m S H A                                                   %
00402 %                                                                             %
00403 %                                                                             %
00404 %                                                                             %
00405 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00406 %
00407 %  TransformSHA224() transforms the SHA224 message accumulator.
00408 %
00409 %  The format of the TransformSHA224 method is:
00410 %
00411 %      TransformSHA224(SHA224Info *sha_info)
00412 %
00413 %  A description of each parameter follows:
00414 %
00415 %    o sha_info: The address of a structure of type SHA224Info.
00416 %
00417 %
00418 */
00419 
00420 static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
00421 {
00422   return((x & y) ^ (~x & z));
00423 }
00424 
00425 static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
00426 {
00427   return((x & y) ^ (x & z) ^ (y & z));
00428 }
00429 
00430 static inline unsigned int Trunc32(unsigned int x)
00431 {
00432   return((unsigned int) (x & 0xffffffffU));
00433 }
00434 
00435 static unsigned int RotateRight(unsigned int x,unsigned int n)
00436 {
00437   return(Trunc32((x >> n) | (x << (32-n))));
00438 }
00439 
00440 static void TransformSHA224(SHA224Info *sha_info)
00441 {
00442 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
00443 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
00444 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
00445 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
00446 
00447   ssize_t
00448     j;
00449 
00450   register ssize_t
00451     i;
00452 
00453   register unsigned char
00454     *p;
00455 
00456   static unsigned int
00457     K[64] =
00458     {
00459       0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
00460       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
00461       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
00462       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
00463       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
00464       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
00465       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
00466       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
00467       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
00468       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
00469       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
00470       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
00471       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
00472     };  /* 32-bit fractional part of the cube root of the first 64 primes */
00473 
00474   unsigned int
00475     A,
00476     B,
00477     C,
00478     D,
00479     E,
00480     F,
00481     G,
00482     H,
00483     shift,
00484     T,
00485     T1,
00486     T2,
00487     W[64];
00488 
00489   shift=32;
00490   p=GetStringInfoDatum(sha_info->message);
00491   if (sha_info->lsb_first == WizardFalse)
00492     {
00493       if (sizeof(unsigned int) <= 4)
00494         for (i=0; i < 16; i++)
00495         {
00496           T=(*((unsigned int *) p));
00497           p+=4;
00498           W[i]=Trunc32(T);
00499         }
00500       else
00501         for (i=0; i < 16; i+=2)
00502         {
00503           T=(*((unsigned int *) p));
00504           p+=8;
00505           W[i]=Trunc32(T >> shift);
00506           W[i+1]=Trunc32(T);
00507         }
00508     }
00509   else
00510     if (sizeof(unsigned int) <= 4)
00511       for (i=0; i < 16; i++)
00512       {
00513         T=(*((unsigned int *) p));
00514         p+=4;
00515         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00516           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00517       }
00518     else
00519       for (i=0; i < 16; i+=2)
00520       {
00521         T=(*((unsigned int *) p));
00522         p+=8;
00523         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00524           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00525         T>>=shift;
00526         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00527           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00528       }
00529   /*
00530     Copy accumulator to registers.
00531   */
00532   A=sha_info->accumulator[0];
00533   B=sha_info->accumulator[1];
00534   C=sha_info->accumulator[2];
00535   D=sha_info->accumulator[3];
00536   E=sha_info->accumulator[4];
00537   F=sha_info->accumulator[5];
00538   G=sha_info->accumulator[6];
00539   H=sha_info->accumulator[7];
00540   for (i=16; i < 64; i++)
00541     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
00542   for (j=0; j < 64; j++)
00543   {
00544     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
00545     T2=Trunc32(Suma0(A)+Maj(A,B,C));
00546     H=G;
00547     G=F;
00548     F=E;
00549     E=Trunc32(D+T1);
00550     D=C;
00551     C=B;
00552     B=A;
00553     A=Trunc32(T1+T2);
00554   }
00555   /*
00556     Add registers back to accumulator.
00557   */
00558   sha_info->accumulator[0]=Trunc32(sha_info->accumulator[0]+A);
00559   sha_info->accumulator[1]=Trunc32(sha_info->accumulator[1]+B);
00560   sha_info->accumulator[2]=Trunc32(sha_info->accumulator[2]+C);
00561   sha_info->accumulator[3]=Trunc32(sha_info->accumulator[3]+D);
00562   sha_info->accumulator[4]=Trunc32(sha_info->accumulator[4]+E);
00563   sha_info->accumulator[5]=Trunc32(sha_info->accumulator[5]+F);
00564   sha_info->accumulator[6]=Trunc32(sha_info->accumulator[6]+G);
00565   /*
00566     Reset working registers.
00567   */
00568   A=0;
00569   B=0;
00570   C=0;
00571   D=0;
00572   E=0;
00573   F=0;
00574   G=0;
00575   H=0;
00576   T=0;
00577   T1=0;
00578   T2=0;
00579   (void) ResetWizardMemory(W,0,sizeof(W));
00580 }
00581 
00582 /*
00583 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00584 %                                                                             %
00585 %                                                                             %
00586 %                                                                             %
00587 %   U p d a t e S H A                                                         %
00588 %                                                                             %
00589 %                                                                             %
00590 %                                                                             %
00591 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00592 %
00593 %  UpdateSHA224() updates the SHA224 message accumulator.
00594 %
00595 %  The format of the UpdateSHA224 method is:
00596 %
00597 %      UpdateSHA224(SHA224Info *sha_info,const StringInfo *message)
00598 %
00599 %  A description of each parameter follows:
00600 %
00601 %    o sha_info: The address of a structure of type SHA224Info.
00602 %
00603 %    o message: The message.
00604 %
00605 %
00606 */
00607 WizardExport void UpdateSHA224(SHA224Info *sha_info,const StringInfo *message)
00608 {
00609   register size_t
00610     i;
00611 
00612   register unsigned char
00613     *p;
00614 
00615   size_t
00616     n;
00617 
00618   unsigned int
00619     length;
00620 
00621   /*
00622     Update the SHA224 accumulator.
00623   */
00624   assert(sha_info != (SHA224Info *) NULL);
00625   assert(sha_info->signature == WizardSignature);
00626   n=GetStringInfoLength(message);
00627   length=Trunc32((unsigned int) (sha_info->low_order+(n << 3)));
00628   if (length < sha_info->low_order)
00629     sha_info->high_order++;
00630   sha_info->low_order=length;
00631   sha_info->high_order+=(unsigned int) (n >> 29);
00632   p=GetStringInfoDatum(message);
00633   if (sha_info->offset != 0)
00634     {
00635       i=GetStringInfoLength(sha_info->message)-sha_info->offset;
00636       if (i > n)
00637         i=n;
00638       (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message)+
00639         sha_info->offset,p,i);
00640       n-=i;
00641       p+=i;
00642       sha_info->offset+=i;
00643       if (sha_info->offset != GetStringInfoLength(sha_info->message))
00644         return;
00645       TransformSHA224(sha_info);
00646     }
00647   while (n >= GetStringInfoLength(sha_info->message))
00648   {
00649     SetStringInfoDatum(sha_info->message,p);
00650     p+=GetStringInfoLength(sha_info->message);
00651     n-=GetStringInfoLength(sha_info->message);
00652     TransformSHA224(sha_info);
00653   }
00654   (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message),p,n);
00655   sha_info->offset=n;
00656   /*
00657     Reset working registers.
00658   */
00659   i=0;
00660   n=0;
00661   length=0;
00662 }