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