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