]> granicus.if.org Git - imagemagick/blob - MagickCore/signature.c
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=10983
[imagemagick] / MagickCore / signature.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %        SSSSS  IIIII   GGGG  N   N   AAA   TTTTT  U   U  RRRR   EEEEE        %
6 %        SS       I    G      NN  N  A   A    T    U   U  R   R  E            %
7 %         SSS     I    G  GG  N N N  AAAAA    T    U   U  RRRR   EEE          %
8 %           SS    I    G   G  N  NN  A   A    T    U   U  R R    E            %
9 %        SSSSS  IIIII   GGG   N   N  A   A    T     UUU   R  R   EEEEE        %
10 %                                                                             %
11 %                                                                             %
12 %         MagickCore Methods to Compute a Message Digest for an Image         %
13 %                                                                             %
14 %                             Software Design                                 %
15 %                                  Cristy                                     %
16 %                              December 1992                                  %
17 %                                                                             %
18 %                                                                             %
19 %  Copyright 1999-2018 ImageMagick Studio LLC, a non-profit organization      %
20 %  dedicated to making software imaging solutions freely available.           %
21 %                                                                             %
22 %  You may not use this file except in compliance with the License.  You may  %
23 %  obtain a copy of the License at                                            %
24 %                                                                             %
25 %    https://imagemagick.org/script/license.php                               %
26 %                                                                             %
27 %  Unless required by applicable law or agreed to in writing, software        %
28 %  distributed under the License is distributed on an "AS IS" BASIS,          %
29 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
30 %  See the License for the specific language governing permissions and        %
31 %  limitations under the License.                                             %
32 %                                                                             %
33 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
34 %
35 %
36 %
37 */
38 \f
39 /*
40   Include declarations.
41 */
42 #include "MagickCore/studio.h"
43 #include "MagickCore/cache.h"
44 #include "MagickCore/exception.h"
45 #include "MagickCore/exception-private.h"
46 #include "MagickCore/property.h"
47 #include "MagickCore/image.h"
48 #include "MagickCore/memory_.h"
49 #include "MagickCore/memory-private.h"
50 #include "MagickCore/pixel-accessor.h"
51 #include "MagickCore/quantum.h"
52 #include "MagickCore/quantum-private.h"
53 #include "MagickCore/signature.h"
54 #include "MagickCore/signature-private.h"
55 #include "MagickCore/string_.h"
56 /*
57   Define declarations.
58 */
59 #define SignatureBlocksize  64
60 #define SignatureDigestsize  32
61 \f
62 /*
63   Typedef declarations.
64 */
65 struct _SignatureInfo
66 {
67   unsigned int
68     digestsize,
69     blocksize;
70
71   StringInfo
72     *digest,
73     *message;
74
75   unsigned int
76     *accumulator,
77     low_order,
78     high_order;
79
80   size_t
81     extent;
82
83   MagickBooleanType
84     lsb_first;
85
86   ssize_t
87     timestamp;
88
89   size_t
90     signature;
91 };
92 \f
93 /*
94   Forward declarations.
95 */
96 static void
97   TransformSignature(SignatureInfo *);
98 \f
99 /*
100 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101 %                                                                             %
102 %                                                                             %
103 %                                                                             %
104 +   A c q u i r e S i g n a t u r e I n f o                                   %
105 %                                                                             %
106 %                                                                             %
107 %                                                                             %
108 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109 %
110 %  AcquireSignatureInfo() allocate the SignatureInfo structure.
111 %
112 %  The format of the AcquireSignatureInfo method is:
113 %
114 %      SignatureInfo *AcquireSignatureInfo(void)
115 %
116 */
117 MagickPrivate SignatureInfo *AcquireSignatureInfo(void)
118 {
119   SignatureInfo
120     *signature_info;
121
122   unsigned long
123     lsb_first;
124
125   signature_info=(SignatureInfo *) AcquireCriticalMemory(
126     sizeof(*signature_info));
127   (void) memset(signature_info,0,sizeof(*signature_info));
128   signature_info->digestsize=SignatureDigestsize;
129   signature_info->blocksize=SignatureBlocksize;
130   signature_info->digest=AcquireStringInfo(SignatureDigestsize);
131   signature_info->message=AcquireStringInfo(SignatureBlocksize);
132   signature_info->accumulator=(unsigned int *) AcquireQuantumMemory(
133     SignatureBlocksize,sizeof(*signature_info->accumulator));
134   if (signature_info->accumulator == (unsigned int *) NULL)
135     ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
136   (void) memset(signature_info->accumulator,0,SignatureBlocksize*
137     sizeof(*signature_info->accumulator));
138   lsb_first=1;
139   signature_info->lsb_first=(int) (*(char *) &lsb_first) == 1 ? MagickTrue :
140     MagickFalse;
141   signature_info->timestamp=(ssize_t) time((time_t *) NULL);
142   signature_info->signature=MagickCoreSignature;
143   InitializeSignature(signature_info);
144   return(signature_info);
145 }
146 \f
147 /*
148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 %                                                                             %
150 %                                                                             %
151 %                                                                             %
152 +   D e s t r o y S i g n a t u r e I n f o                                   %
153 %                                                                             %
154 %                                                                             %
155 %                                                                             %
156 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157 %
158 %  DestroySignatureInfo() zeros memory associated with the SignatureInfo
159 %  structure.
160 %
161 %  The format of the DestroySignatureInfo method is:
162 %
163 %      SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
164 %
165 %  A description of each parameter follows:
166 %
167 %    o signature_info: the cipher signature_info.
168 %
169 */
170 MagickPrivate SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
171 {
172   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
173   assert(signature_info != (SignatureInfo *) NULL);
174   assert(signature_info->signature == MagickCoreSignature);
175   if (signature_info->accumulator != (unsigned int *) NULL)
176     signature_info->accumulator=(unsigned int *) RelinquishMagickMemory(
177       signature_info->accumulator);
178   if (signature_info->message != (StringInfo *) NULL)
179     signature_info->message=DestroyStringInfo(signature_info->message);
180   if (signature_info->digest != (StringInfo *) NULL)
181     signature_info->digest=DestroyStringInfo(signature_info->digest);
182   signature_info->signature=(~MagickCoreSignature);
183   signature_info=(SignatureInfo *) RelinquishMagickMemory(signature_info);
184   return(signature_info);
185 }
186 \f
187 /*
188 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
189 %                                                                             %
190 %                                                                             %
191 %                                                                             %
192 +   F i n a l i z e S i g n a t u r e                                         %
193 %                                                                             %
194 %                                                                             %
195 %                                                                             %
196 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
197 %
198 %  FinalizeSignature() finalizes the Signature message accumulator computation.
199 %
200 %  The format of the FinalizeSignature method is:
201 %
202 %      FinalizeSignature(SignatureInfo *signature_info)
203 %
204 %  A description of each parameter follows:
205 %
206 %    o signature_info: the address of a structure of type SignatureInfo.
207 %
208 */
209 MagickPrivate void FinalizeSignature(SignatureInfo *signature_info)
210 {
211   register ssize_t
212     i;
213
214   register unsigned char
215     *q;
216
217   register unsigned int
218     *p;
219
220   size_t
221     extent;
222
223   unsigned char
224     *datum;
225
226   unsigned int
227     high_order,
228     low_order;
229
230   /*
231     Add padding and return the message accumulator.
232   */
233   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
234   assert(signature_info != (SignatureInfo *) NULL);
235   assert(signature_info->signature == MagickCoreSignature);
236   low_order=signature_info->low_order;
237   high_order=signature_info->high_order;
238   extent=((low_order >> 3) & 0x3f);
239   datum=GetStringInfoDatum(signature_info->message);
240   datum[extent++]=(unsigned char) 0x80;
241   if (extent <= (unsigned int) (GetStringInfoLength(signature_info->message)-8))
242     (void) memset(datum+extent,0,GetStringInfoLength(
243       signature_info->message)-8-extent);
244   else
245     {
246       (void) memset(datum+extent,0,GetStringInfoLength(
247         signature_info->message)-extent);
248       TransformSignature(signature_info);
249       (void) memset(datum,0,GetStringInfoLength(
250         signature_info->message)-8);
251     }
252   datum[56]=(unsigned char) (high_order >> 24);
253   datum[57]=(unsigned char) (high_order >> 16);
254   datum[58]=(unsigned char) (high_order >> 8);
255   datum[59]=(unsigned char) high_order;
256   datum[60]=(unsigned char) (low_order >> 24);
257   datum[61]=(unsigned char) (low_order >> 16);
258   datum[62]=(unsigned char) (low_order >> 8);
259   datum[63]=(unsigned char) low_order;
260   TransformSignature(signature_info);
261   p=signature_info->accumulator;
262   q=GetStringInfoDatum(signature_info->digest);
263   for (i=0; i < (SignatureDigestsize/4); i++)
264   {
265     *q++=(unsigned char) ((*p >> 24) & 0xff);
266     *q++=(unsigned char) ((*p >> 16) & 0xff);
267     *q++=(unsigned char) ((*p >> 8) & 0xff);
268     *q++=(unsigned char) (*p & 0xff);
269     p++;
270   }
271 }
272 \f
273 /*
274 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
275 %                                                                             %
276 %                                                                             %
277 %                                                                             %
278 +   G e t S i g n a t u r e B l o c k s i z e                                 %
279 %                                                                             %
280 %                                                                             %
281 %                                                                             %
282 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
283 %
284 %  GetSignatureBlocksize() returns the Signature blocksize.
285 %
286 %  The format of the GetSignatureBlocksize method is:
287 %
288 %      unsigned int *GetSignatureBlocksize(const SignatureInfo *signature_info)
289 %
290 %  A description of each parameter follows:
291 %
292 %    o signature_info: the signature info.
293 %
294 */
295 MagickPrivate unsigned int GetSignatureBlocksize(
296   const SignatureInfo *signature_info)
297 {
298   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
299   assert(signature_info != (SignatureInfo *) NULL);
300   assert(signature_info->signature == MagickCoreSignature);
301   return(signature_info->blocksize);
302 }
303 \f
304 /*
305 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
306 %                                                                             %
307 %                                                                             %
308 %                                                                             %
309 +   G e t S i g n a t u r e D i g e s t                                       %
310 %                                                                             %
311 %                                                                             %
312 %                                                                             %
313 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
314 %
315 %  GetSignatureDigest() returns the signature digest.
316 %
317 %  The format of the GetSignatureDigest method is:
318 %
319 %      const StringInfo *GetSignatureDigest(const SignatureInfo *signature_info)
320 %
321 %  A description of each parameter follows:
322 %
323 %    o signature_info: the signature info.
324 %
325 */
326 MagickPrivate const StringInfo *GetSignatureDigest(
327   const SignatureInfo *signature_info)
328 {
329   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
330   assert(signature_info != (SignatureInfo *) NULL);
331   assert(signature_info->signature == MagickCoreSignature);
332   return(signature_info->digest);
333 }
334 \f
335 /*
336 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
337 %                                                                             %
338 %                                                                             %
339 %                                                                             %
340 +   G e t S i g n a t u r e D i g e s t s i z e                               %
341 %                                                                             %
342 %                                                                             %
343 %                                                                             %
344 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
345 %
346 %  GetSignatureDigestsize() returns the Signature digest size.
347 %
348 %  The format of the GetSignatureDigestsize method is:
349 %
350 %      unsigned int *GetSignatureDigestsize(const SignatureInfo *signature_info)
351 %
352 %  A description of each parameter follows:
353 %
354 %    o signature_info: the signature info.
355 %
356 */
357 MagickPrivate unsigned int GetSignatureDigestsize(
358   const SignatureInfo *signature_info)
359 {
360   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
361   assert(signature_info != (SignatureInfo *) NULL);
362   assert(signature_info->signature == MagickCoreSignature);
363   return(signature_info->digestsize);
364 }
365 \f
366 /*
367 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
368 %                                                                             %
369 %                                                                             %
370 %                                                                             %
371 +   I n i t i a l i z e S i g n a t u r e                                     %
372 %                                                                             %
373 %                                                                             %
374 %                                                                             %
375 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
376 %
377 %  InitializeSignature() initializes the Signature accumulator.
378 %
379 %  The format of the DestroySignatureInfo method is:
380 %
381 %      void InitializeSignatureInfo(SignatureInfo *signature_info)
382 %
383 %  A description of each parameter follows:
384 %
385 %    o signature_info: the cipher signature_info.
386 %
387 */
388 MagickPrivate void InitializeSignature(SignatureInfo *signature_info)
389 {
390   (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
391   assert(signature_info != (SignatureInfo *) NULL);
392   assert(signature_info->signature == MagickCoreSignature);
393   signature_info->accumulator[0]=0x6a09e667U;
394   signature_info->accumulator[1]=0xbb67ae85U;
395   signature_info->accumulator[2]=0x3c6ef372U;
396   signature_info->accumulator[3]=0xa54ff53aU;
397   signature_info->accumulator[4]=0x510e527fU;
398   signature_info->accumulator[5]=0x9b05688cU;
399   signature_info->accumulator[6]=0x1f83d9abU;
400   signature_info->accumulator[7]=0x5be0cd19U;
401   signature_info->low_order=0;
402   signature_info->high_order=0;
403   signature_info->extent=0;
404 }
405 \f
406 /*
407 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408 %                                                                             %
409 %                                                                             %
410 %                                                                             %
411 +   S e t S i g n a t u r e D i g e s t                                       %
412 %                                                                             %
413 %                                                                             %
414 %                                                                             %
415 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
416 %
417 %  SetSignatureDigest() set the signature digest.
418 %
419 %  The format of the SetSignatureDigest method is:
420 %
421 %      SetSignatureDigest(SignatureInfo *signature_info,
422 %        const StringInfo *digest)
423 %
424 %  A description of each parameter follows:
425 %
426 %    o signature_info: the signature info.
427 %
428 %    o digest: the digest.
429 %
430 */
431 MagickPrivate void SetSignatureDigest(SignatureInfo *signature_info,
432   const StringInfo *digest)
433 {
434   /*
435     Set the signature accumulator.
436   */
437   assert(signature_info != (SignatureInfo *) NULL);
438   assert(signature_info->signature == MagickCoreSignature);
439   SetStringInfo(signature_info->digest,digest);
440 }
441 \f
442 /*
443 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
444 %                                                                             %
445 %                                                                             %
446 %                                                                             %
447 %   S i g n a t u r e I m a g e                                               %
448 %                                                                             %
449 %                                                                             %
450 %                                                                             %
451 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
452 %
453 %  SignatureImage() computes a message digest from an image pixel stream with
454 %  an implementation of the NIST SHA-256 Message Digest algorithm.  This
455 %  signature uniquely identifies the image and is convenient for determining
456 %  if an image has been modified or whether two images are identical.
457 %
458 %  The format of the SignatureImage method is:
459 %
460 %      MagickBooleanType SignatureImage(Image *image,ExceptionInfo *exception)
461 %
462 %  A description of each parameter follows:
463 %
464 %    o image: the image.
465 %
466 %    o exception: return any errors or warnings in this structure.
467 %
468 */
469 MagickExport MagickBooleanType SignatureImage(Image *image,
470   ExceptionInfo *exception)
471 {
472   CacheView
473     *image_view;
474
475   char
476     *hex_signature;
477
478   double
479     pixel;
480
481   register const Quantum
482     *p;
483
484   SignatureInfo
485     *signature_info;
486
487   ssize_t
488     y;
489
490   StringInfo
491     *signature;
492
493   unsigned char
494     *pixels;
495
496   /*
497     Compute image digital signature.
498   */
499   assert(image != (Image *) NULL);
500   assert(image->signature == MagickCoreSignature);
501   if (image->debug != MagickFalse)
502     (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
503   signature_info=AcquireSignatureInfo();
504   signature=AcquireStringInfo(GetPixelChannels(image)*image->columns*
505     sizeof(pixel));
506   image_view=AcquireVirtualCacheView(image,exception);
507   for (y=0; y < (ssize_t) image->rows; y++)
508   {
509     register ssize_t
510       x;
511
512     register unsigned char
513       *q;
514
515     p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
516     if (p == (const Quantum *) NULL)
517       break;
518     SetStringInfoLength(signature,GetPixelChannels(image)*image->columns*
519       sizeof(pixel));
520     pixels=GetStringInfoDatum(signature);
521     q=pixels;
522     for (x=0; x < (ssize_t) image->columns; x++)
523     {
524       register ssize_t
525         i;
526
527       if (GetPixelReadMask(image,p) <= (QuantumRange/2))
528         {
529           p+=GetPixelChannels(image);
530           continue;
531         }
532       for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
533       {
534         register ssize_t
535           j;
536
537         PixelChannel channel = GetPixelChannelChannel(image,i);
538         PixelTrait traits = GetPixelChannelTraits(image,channel);
539         if (traits == UndefinedPixelTrait)
540           continue;
541         pixel=QuantumScale*p[i];
542         if (signature_info->lsb_first == MagickFalse)
543           for (j=(ssize_t) sizeof(pixel)-1; j >= 0; j--)
544             *q++=(unsigned char) ((unsigned char *) &pixel)[j];
545         else
546           for (j=0; j < (ssize_t) sizeof(pixel); j++)
547             *q++=(unsigned char) ((unsigned char *) &pixel)[j];
548       }
549       p+=GetPixelChannels(image);
550     }
551     SetStringInfoLength(signature,(size_t) (q-pixels));
552     UpdateSignature(signature_info,signature);
553   }
554   image_view=DestroyCacheView(image_view);
555   FinalizeSignature(signature_info);
556   hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
557   (void) DeleteImageProperty(image,"signature");
558   (void) SetImageProperty(image,"signature",hex_signature,exception);
559   /*
560     Free resources.
561   */
562   hex_signature=DestroyString(hex_signature);
563   signature=DestroyStringInfo(signature);
564   signature_info=DestroySignatureInfo(signature_info);
565   return(MagickTrue);
566 }
567 \f
568 /*
569 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
570 %                                                                             %
571 %                                                                             %
572 %                                                                             %
573 +   T r a n s f o r m S i g n a t u r e                                       %
574 %                                                                             %
575 %                                                                             %
576 %                                                                             %
577 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
578 %
579 %  TransformSignature() transforms the Signature message accumulator.
580 %
581 %  The format of the TransformSignature method is:
582 %
583 %      TransformSignature(SignatureInfo *signature_info)
584 %
585 %  A description of each parameter follows:
586 %
587 %    o signature_info: the address of a structure of type SignatureInfo.
588 %
589 */
590
591 static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
592 {
593   return((x & y) ^ (~x & z));
594 }
595
596 static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
597 {
598   return((x & y) ^ (x & z) ^ (y & z));
599 }
600
601 static inline unsigned int Trunc32(unsigned int x)
602 {
603   return((unsigned int) (x & 0xffffffffU));
604 }
605
606 static unsigned int RotateRight(unsigned int x,unsigned int n)
607 {
608   return(Trunc32((x >> n) | (x << (32-n))));
609 }
610
611 static void TransformSignature(SignatureInfo *signature_info)
612 {
613 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
614 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
615 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
616 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
617
618   register ssize_t
619     i;
620
621   register unsigned char
622     *p;
623
624   ssize_t
625     j;
626
627   static unsigned int
628     K[64] =
629     {
630       0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
631       0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
632       0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
633       0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
634       0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
635       0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
636       0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
637       0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
638       0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
639       0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
640       0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
641       0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
642       0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
643     };  /* 32-bit fractional part of the cube root of the first 64 primes */
644
645   unsigned int
646     A,
647     B,
648     C,
649     D,
650     E,
651     F,
652     G,
653     H,
654     shift,
655     T,
656     T1,
657     T2,
658     W[64];
659
660   shift=32;
661   p=GetStringInfoDatum(signature_info->message);
662   if (signature_info->lsb_first == MagickFalse)
663     {
664 DisableMSCWarning(4127)
665       if (sizeof(unsigned int) <= 4)
666 RestoreMSCWarning
667         for (i=0; i < 16; i++)
668         {
669           T=(*((unsigned int *) p));
670           p+=4;
671           W[i]=Trunc32(T);
672         }
673       else
674         for (i=0; i < 16; i+=2)
675         {
676           T=(*((unsigned int *) p));
677           p+=8;
678           W[i]=Trunc32(T >> shift);
679           W[i+1]=Trunc32(T);
680         }
681     }
682   else
683 DisableMSCWarning(4127)
684     if (sizeof(unsigned int) <= 4)
685 RestoreMSCWarning
686       for (i=0; i < 16; i++)
687       {
688         T=(*((unsigned int *) p));
689         p+=4;
690         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
691           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
692       }
693     else
694       for (i=0; i < 16; i+=2)
695       {
696         T=(*((unsigned int *) p));
697         p+=8;
698         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
699           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
700         T>>=shift;
701         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
702           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
703       }
704   /*
705     Copy accumulator to registers.
706   */
707   A=signature_info->accumulator[0];
708   B=signature_info->accumulator[1];
709   C=signature_info->accumulator[2];
710   D=signature_info->accumulator[3];
711   E=signature_info->accumulator[4];
712   F=signature_info->accumulator[5];
713   G=signature_info->accumulator[6];
714   H=signature_info->accumulator[7];
715   for (i=16; i < 64; i++)
716     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
717   for (j=0; j < 64; j++)
718   {
719     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
720     T2=Trunc32(Suma0(A)+Maj(A,B,C));
721     H=G;
722     G=F;
723     F=E;
724     E=Trunc32(D+T1);
725     D=C;
726     C=B;
727     B=A;
728     A=Trunc32(T1+T2);
729   }
730   /*
731     Add registers back to accumulator.
732   */
733   signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
734   signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
735   signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
736   signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
737   signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
738   signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
739   signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
740   signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
741   /*
742     Reset working registers.
743   */
744   A=0;
745   B=0;
746   C=0;
747   D=0;
748   E=0;
749   F=0;
750   G=0;
751   H=0;
752   T=0;
753   T1=0;
754   T2=0;
755   (void) memset(W,0,sizeof(W));
756 }
757 \f
758 /*
759 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
760 %                                                                             %
761 %                                                                             %
762 %                                                                             %
763 +   U p d a t e S i g n a t u r e                                             %
764 %                                                                             %
765 %                                                                             %
766 %                                                                             %
767 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
768 %
769 %  UpdateSignature() updates the Signature message accumulator.
770 %
771 %  The format of the UpdateSignature method is:
772 %
773 %      UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
774 %
775 %  A description of each parameter follows:
776 %
777 %    o signature_info: the address of a structure of type SignatureInfo.
778 %
779 %    o message: the message.
780 %
781 */
782 MagickPrivate void UpdateSignature(SignatureInfo *signature_info,
783   const StringInfo *message)
784 {
785   register size_t
786     i;
787
788   register unsigned char
789     *p;
790
791   size_t
792     n;
793
794   unsigned int
795     length;
796
797   /*
798     Update the Signature accumulator.
799   */
800   assert(signature_info != (SignatureInfo *) NULL);
801   assert(signature_info->signature == MagickCoreSignature);
802   n=GetStringInfoLength(message);
803   length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
804   if (length < signature_info->low_order)
805     signature_info->high_order++;
806   signature_info->low_order=length;
807   signature_info->high_order+=(unsigned int) n >> 29;
808   p=GetStringInfoDatum(message);
809   if (signature_info->extent != 0)
810     {
811       i=GetStringInfoLength(signature_info->message)-signature_info->extent;
812       if (i > n)
813         i=n;
814       (void) memcpy(GetStringInfoDatum(signature_info->message)+
815         signature_info->extent,p,i);
816       n-=i;
817       p+=i;
818       signature_info->extent+=i;
819       if (signature_info->extent != GetStringInfoLength(signature_info->message))
820         return;
821       TransformSignature(signature_info);
822     }
823   while (n >= GetStringInfoLength(signature_info->message))
824   {
825     SetStringInfoDatum(signature_info->message,p);
826     p+=GetStringInfoLength(signature_info->message);
827     n-=GetStringInfoLength(signature_info->message);
828     TransformSignature(signature_info);
829   }
830   (void) memcpy(GetStringInfoDatum(signature_info->message),p,n);
831   signature_info->extent=n;
832 }