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