MagickCore 6.9.13
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/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 "magick/studio.h"
43#include "magick/cache.h"
44#include "magick/exception.h"
45#include "magick/exception-private.h"
46#include "magick/property.h"
47#include "magick/image.h"
48#include "magick/memory_.h"
49#include "magick/quantum.h"
50#include "magick/quantum-private.h"
51#include "magick/signature.h"
52#include "magick/signature-private.h"
53#include "magick/string_.h"
54#include "magick/timer-private.h"
55/*
56 Define declarations.
57*/
58#define SignatureBlocksize 64
59#define SignatureDigestsize 32
60
61/*
62 Typedef declarations.
63*/
65{
66 unsigned int
67 digestsize,
68 blocksize;
69
71 *digest,
72 *message;
73
74 unsigned int
75 *accumulator,
76 low_order,
77 high_order;
78
79 size_t
80 extent;
81
82 MagickBooleanType
83 lsb_first;
84
85 time_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*/
116MagickExport SignatureInfo *AcquireSignatureInfo(void)
117{
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) 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=GetMagickTime();
142 signature_info->signature=MagickCoreSignature;
143 InitializeSignature(signature_info);
144 return(signature_info);
145}
146
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*/
170MagickExport SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
171{
172 assert(signature_info != (SignatureInfo *) NULL);
173 assert(signature_info->signature == MagickCoreSignature);
174 if (IsEventLogging() != MagickFalse)
175 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
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*/
210MagickExport 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 assert(signature_info != (SignatureInfo *) NULL);
235 assert(signature_info->signature == MagickCoreSignature);
236 if (IsEventLogging() != MagickFalse)
237 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
238 low_order=signature_info->low_order;
239 high_order=signature_info->high_order;
240 extent=((low_order >> 3) & 0x3f);
241 datum=GetStringInfoDatum(signature_info->message);
242 datum[extent++]=(unsigned char) 0x80;
243 if (extent <= (unsigned int) (GetStringInfoLength(signature_info->message)-8))
244 (void) memset(datum+extent,0,GetStringInfoLength(
245 signature_info->message)-8-extent);
246 else
247 {
248 (void) memset(datum+extent,0,GetStringInfoLength(
249 signature_info->message)-extent);
250 TransformSignature(signature_info);
251 (void) memset(datum,0,GetStringInfoLength(
252 signature_info->message)-8);
253 }
254 datum[56]=(unsigned char) (high_order >> 24);
255 datum[57]=(unsigned char) (high_order >> 16);
256 datum[58]=(unsigned char) (high_order >> 8);
257 datum[59]=(unsigned char) high_order;
258 datum[60]=(unsigned char) (low_order >> 24);
259 datum[61]=(unsigned char) (low_order >> 16);
260 datum[62]=(unsigned char) (low_order >> 8);
261 datum[63]=(unsigned char) low_order;
262 TransformSignature(signature_info);
263 p=signature_info->accumulator;
264 q=GetStringInfoDatum(signature_info->digest);
265 for (i=0; i < (SignatureDigestsize/4); i++)
266 {
267 *q++=(unsigned char) ((*p >> 24) & 0xff);
268 *q++=(unsigned char) ((*p >> 16) & 0xff);
269 *q++=(unsigned char) ((*p >> 8) & 0xff);
270 *q++=(unsigned char) (*p & 0xff);
271 p++;
272 }
273}
274
275/*
276%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
277% %
278% %
279% %
280+ G e t S i g n a t u r e B l o c k s i z e %
281% %
282% %
283% %
284%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
285%
286% GetSignatureBlocksize() returns the Signature blocksize.
287%
288% The format of the GetSignatureBlocksize method is:
289%
290% unsigned int *GetSignatureBlocksize(const SignatureInfo *signature_info)
291%
292% A description of each parameter follows:
293%
294% o signature_info: the signature info.
295%
296*/
297MagickExport unsigned int GetSignatureBlocksize(
298 const SignatureInfo *signature_info)
299{
300 assert(signature_info != (SignatureInfo *) NULL);
301 assert(signature_info->signature == MagickCoreSignature);
302 if (IsEventLogging() != MagickFalse)
303 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
304 return(signature_info->blocksize);
305}
306
307/*
308%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
309% %
310% %
311% %
312+ G e t S i g n a t u r e D i g e s t %
313% %
314% %
315% %
316%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
317%
318% GetSignatureDigest() returns the signature digest.
319%
320% The format of the GetSignatureDigest method is:
321%
322% const StringInfo *GetSignatureDigest(const SignatureInfo *signature_info)
323%
324% A description of each parameter follows:
325%
326% o signature_info: the signature info.
327%
328*/
329MagickExport const StringInfo *GetSignatureDigest(
330 const SignatureInfo *signature_info)
331{
332 assert(signature_info != (SignatureInfo *) NULL);
333 assert(signature_info->signature == MagickCoreSignature);
334 if (IsEventLogging() != MagickFalse)
335 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
336 return(signature_info->digest);
337}
338
339/*
340%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
341% %
342% %
343% %
344+ G e t S i g n a t u r e D i g e s t s i z e %
345% %
346% %
347% %
348%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
349%
350% GetSignatureDigestsize() returns the Signature digest size.
351%
352% The format of the GetSignatureDigestsize method is:
353%
354% unsigned int *GetSignatureDigestsize(const SignatureInfo *signature_info)
355%
356% A description of each parameter follows:
357%
358% o signature_info: the signature info.
359%
360*/
361MagickExport unsigned int GetSignatureDigestsize(
362 const SignatureInfo *signature_info)
363{
364 assert(signature_info != (SignatureInfo *) NULL);
365 assert(signature_info->signature == MagickCoreSignature);
366 if (IsEventLogging() != MagickFalse)
367 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
368 return(signature_info->digestsize);
369}
370
371/*
372%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
373% %
374% %
375% %
376+ I n i t i a l i z e S i g n a t u r e %
377% %
378% %
379% %
380%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
381%
382% InitializeSignature() initializes the Signature accumulator.
383%
384% The format of the DestroySignatureInfo method is:
385%
386% void InitializeSignatureInfo(SignatureInfo *signature_info)
387%
388% A description of each parameter follows:
389%
390% o signature_info: the cipher signature_info.
391%
392*/
393MagickExport void InitializeSignature(SignatureInfo *signature_info)
394{
395 assert(signature_info != (SignatureInfo *) NULL);
396 assert(signature_info->signature == MagickCoreSignature);
397 if (IsEventLogging() != MagickFalse)
398 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
399 signature_info->accumulator[0]=0x6a09e667U;
400 signature_info->accumulator[1]=0xbb67ae85U;
401 signature_info->accumulator[2]=0x3c6ef372U;
402 signature_info->accumulator[3]=0xa54ff53aU;
403 signature_info->accumulator[4]=0x510e527fU;
404 signature_info->accumulator[5]=0x9b05688cU;
405 signature_info->accumulator[6]=0x1f83d9abU;
406 signature_info->accumulator[7]=0x5be0cd19U;
407 signature_info->low_order=0;
408 signature_info->high_order=0;
409 signature_info->extent=0;
410}
411
412/*
413%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
414% %
415% %
416% %
417+ S e t S i g n a t u r e D i g e s t %
418% %
419% %
420% %
421%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
422%
423% SetSignatureDigest() set the signature digest.
424%
425% The format of the SetSignatureDigest method is:
426%
427% SetSignatureDigest(SignatureInfo *signature_info,
428% const StringInfo *digest)
429%
430% A description of each parameter follows:
431%
432% o signature_info: the signature info.
433%
434% o digest: the digest.
435%
436*/
437MagickExport void SetSignatureDigest(SignatureInfo *signature_info,
438 const StringInfo *digest)
439{
440 /*
441 Set the signature accumulator.
442 */
443 assert(signature_info != (SignatureInfo *) NULL);
444 assert(signature_info->signature == MagickCoreSignature);
445 SetStringInfo(signature_info->digest,digest);
446}
447
448/*
449%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
450% %
451% %
452% %
453% S i g n a t u r e I m a g e %
454% %
455% %
456% %
457%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
458%
459% SignatureImage() computes a message digest from an image pixel stream with
460% an implementation of the NIST SHA-256 Message Digest algorithm. This
461% signature uniquely identifies the image and is convenient for determining
462% if an image has been modified or whether two images are identical.
463%
464% The format of the SignatureImage method is:
465%
466% MagickBooleanType SignatureImage(Image *image)
467%
468% A description of each parameter follows:
469%
470% o image: the image.
471%
472*/
473MagickExport MagickBooleanType SignatureImage(Image *image)
474{
476 *image_view;
477
478 char
479 *hex_signature;
480
482 *exception;
483
485 *quantum_info;
486
487 QuantumType
488 quantum_type;
489
490 const PixelPacket
491 *p;
492
494 *signature_info;
495
496 size_t
497 length;
498
499 ssize_t
500 y;
501
503 *signature;
504
505 unsigned char
506 *pixels;
507
508 /*
509 Compute image digital signature.
510 */
511 assert(image != (Image *) NULL);
512 assert(image->signature == MagickCoreSignature);
513 if (IsEventLogging() != MagickFalse)
514 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
515 exception=(&image->exception);
516 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
517 if (quantum_info == (QuantumInfo *) NULL)
518 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
519 image->filename);
520 quantum_type=RGBQuantum;
521 if (image->matte != MagickFalse)
522 quantum_type=RGBAQuantum;
523 if (image->colorspace == CMYKColorspace)
524 {
525 quantum_type=CMYKQuantum;
526 if (image->matte != MagickFalse)
527 quantum_type=CMYKAQuantum;
528 }
529 signature_info=AcquireSignatureInfo();
530 signature=AcquireStringInfo(quantum_info->extent);
531 pixels=GetQuantumPixels(quantum_info);
532 image_view=AcquireVirtualCacheView(image,exception);
533 for (y=0; y < (ssize_t) image->rows; y++)
534 {
535 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
536 if (p == (const PixelPacket *) NULL)
537 break;
538 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
539 pixels,&image->exception);
540 SetStringInfoLength(signature,length);
541 SetStringInfoDatum(signature,pixels);
542 UpdateSignature(signature_info,signature);
543 }
544 image_view=DestroyCacheView(image_view);
545 quantum_info=DestroyQuantumInfo(quantum_info);
546 FinalizeSignature(signature_info);
547 hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
548 (void) DeleteImageProperty(image,"signature");
549 (void) SetImageProperty(image,"signature",hex_signature);
550 /*
551 Free resources.
552 */
553 hex_signature=DestroyString(hex_signature);
554 signature=DestroyStringInfo(signature);
555 signature_info=DestroySignatureInfo(signature_info);
556 return(MagickTrue);
557}
558
559/*
560%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
561% %
562% %
563% %
564+ T r a n s f o r m S i g n a t u r e %
565% %
566% %
567% %
568%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
569%
570% TransformSignature() transforms the Signature message accumulator.
571%
572% The format of the TransformSignature method is:
573%
574% TransformSignature(SignatureInfo *signature_info)
575%
576% A description of each parameter follows:
577%
578% o signature_info: the address of a structure of type SignatureInfo.
579%
580*/
581static void TransformSignature(SignatureInfo *signature_info)
582{
583#define Ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
584#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
585#define RotateRight(x,n) (Trunc32(((x) >> n) | ((x) << (32-n))))
586#define Sigma0(x) (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
587#define Sigma1(x) (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
588#define Suma0(x) (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
589#define Suma1(x) (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
590#define Trunc32(x) ((unsigned int) ((x) & 0xffffffffU))
591
592 ssize_t
593 i;
594
595 unsigned char
596 *p;
597
598 ssize_t
599 j;
600
601 static const unsigned int
602 K[64] =
603 {
604 0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
605 0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
606 0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
607 0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
608 0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
609 0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
610 0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
611 0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
612 0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
613 0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
614 0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
615 0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
616 0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
617 }; /* 32-bit fractional part of the cube root of the first 64 primes */
618
619 unsigned int
620 A = 0,
621 B,
622 C,
623 D,
624 E,
625 F,
626 G,
627 H,
628 shift,
629 T,
630 T1,
631 T2,
632 W[64];
633
634 shift=32;
635 p=GetStringInfoDatum(signature_info->message);
636 if (signature_info->lsb_first == MagickFalse)
637 {
638DisableMSCWarning(4127)
639 if (sizeof(unsigned int) <= 4)
640RestoreMSCWarning
641 for (i=0; i < 16; i++)
642 {
643 T=(*((unsigned int *) p));
644 p+=(ptrdiff_t) 4;
645 W[i]=Trunc32(T);
646 }
647 else
648 for (i=0; i < 16; i+=2)
649 {
650 T=(*((unsigned int *) p));
651 p+=(ptrdiff_t) 8;
652 W[i]=Trunc32(T >> shift);
653 W[i+1]=Trunc32(T);
654 }
655 }
656 else
657DisableMSCWarning(4127)
658 if (sizeof(unsigned int) <= 4)
659RestoreMSCWarning
660 for (i=0; i < 16; i++)
661 {
662 T=(*((unsigned int *) p));
663 p+=(ptrdiff_t) 4;
664 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
665 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
666 }
667 else
668 for (i=0; i < 16; i+=2)
669 {
670 T=(*((unsigned int *) p));
671 p+=(ptrdiff_t) 8;
672 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
673 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
674 T>>=shift;
675 W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
676 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
677 }
678 /*
679 Copy accumulator to registers.
680 */
681 A=signature_info->accumulator[0];
682 B=signature_info->accumulator[1];
683 C=signature_info->accumulator[2];
684 D=signature_info->accumulator[3];
685 E=signature_info->accumulator[4];
686 F=signature_info->accumulator[5];
687 G=signature_info->accumulator[6];
688 H=signature_info->accumulator[7];
689 for (i=16; i < 64; i++)
690 W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
691 for (j=0; j < 64; j++)
692 {
693 T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
694 T2=Trunc32(Suma0(A)+Maj(A,B,C));
695 H=G;
696 G=F;
697 F=E;
698 E=Trunc32(D+T1);
699 D=C;
700 C=B;
701 B=A;
702 A=Trunc32(T1+T2);
703 }
704 /*
705 Add registers back to accumulator.
706 */
707 signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
708 signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
709 signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
710 signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
711 signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
712 signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
713 signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
714 signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
715 /*
716 Reset working registers.
717 */
718 A=0;
719 B=0;
720 C=0;
721 D=0;
722 E=0;
723 F=0;
724 G=0;
725 H=0;
726 T=0;
727 T1=0;
728 T2=0;
729 (void) ResetMagickMemory(W,0,sizeof(W));
730}
731
732/*
733%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
734% %
735% %
736% %
737+ U p d a t e S i g n a t u r e %
738% %
739% %
740% %
741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742%
743% UpdateSignature() updates the Signature message accumulator.
744%
745% The format of the UpdateSignature method is:
746%
747% UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
748%
749% A description of each parameter follows:
750%
751% o signature_info: the address of a structure of type SignatureInfo.
752%
753% o message: the message.
754%
755*/
756MagickExport void UpdateSignature(SignatureInfo *signature_info,
757 const StringInfo *message)
758{
759 size_t
760 i;
761
762 unsigned char
763 *p;
764
765 size_t
766 n;
767
768 unsigned int
769 length;
770
771 /*
772 Update the Signature accumulator.
773 */
774 assert(signature_info != (SignatureInfo *) NULL);
775 assert(signature_info->signature == MagickCoreSignature);
776 n=GetStringInfoLength(message);
777 length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
778 if (length < signature_info->low_order)
779 signature_info->high_order++;
780 signature_info->low_order=length;
781 signature_info->high_order+=(unsigned int) (n >> 29);
782 p=GetStringInfoDatum(message);
783 if (signature_info->extent != 0)
784 {
785 i=GetStringInfoLength(signature_info->message)-signature_info->extent;
786 if (i > n)
787 i=n;
788 (void) memcpy(GetStringInfoDatum(signature_info->message)+
789 signature_info->extent,p,i);
790 n-=i;
791 p+=(ptrdiff_t) i;
792 signature_info->extent+=i;
793 if (signature_info->extent !=
794 GetStringInfoLength(signature_info->message))
795 return;
796 TransformSignature(signature_info);
797 }
798 while (n >= GetStringInfoLength(signature_info->message))
799 {
800 SetStringInfoDatum(signature_info->message,p);
801 p+=(ptrdiff_t) GetStringInfoLength(signature_info->message);
802 n-=GetStringInfoLength(signature_info->message);
803 TransformSignature(signature_info);
804 }
805 (void) memcpy(GetStringInfoDatum(signature_info->message),p,n);
806 signature_info->extent=n;
807}