blob: 1a7d0007d3f0d2049532a78a023d59794e0142eb [file] [log] [blame]
cristy3ed852e2009-09-05 21:47:34 +00001/*
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% John Cristy %
16% December 1992 %
17% %
18% %
cristy16af1cb2009-12-11 21:38:29 +000019% Copyright 1999-2010 ImageMagick Studio LLC, a non-profit organization %
cristy3ed852e2009-09-05 21:47:34 +000020% 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 "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/*
55 Define declarations.
56*/
57#define SignatureBlocksize 64
58#define SignatureDigestsize 32
59
60/*
61 Typedef declarations.
62*/
63struct _SignatureInfo
cristy82b15832009-10-06 19:17:37 +000064{
cristy3ed852e2009-09-05 21:47:34 +000065 unsigned int
66 digestsize,
67 blocksize;
68
69 StringInfo
70 *digest,
71 *message;
72
73 unsigned int
74 *accumulator,
75 low_order,
76 high_order;
77
78 size_t
79 offset;
80
81 MagickBooleanType
82 lsb_first;
83
cristybb503372010-05-27 20:51:26 +000084 ssize_t
cristy3ed852e2009-09-05 21:47:34 +000085 timestamp;
86
cristybb503372010-05-27 20:51:26 +000087 size_t
cristy3ed852e2009-09-05 21:47:34 +000088 signature;
89};
90
91/*
92 Forward declarations.
93*/
94static void
95 TransformSignature(SignatureInfo *);
96
97/*
98%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
99% %
100% %
101% %
102+ A c q u i r e S i g n a t u r e I n f o %
103% %
104% %
105% %
106%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
107%
108% AcquireSignatureInfo() allocate the SignatureInfo structure.
109%
110% The format of the AcquireSignatureInfo method is:
111%
112% SignatureInfo *AcquireSignatureInfo(void)
113%
114*/
115MagickExport SignatureInfo *AcquireSignatureInfo(void)
116{
117 SignatureInfo
118 *signature_info;
119
120 unsigned int
121 lsb_first;
122
cristy90823212009-12-12 20:48:33 +0000123 signature_info=(SignatureInfo *) AcquireAlignedMemory(1,sizeof(*signature_info));
cristy3ed852e2009-09-05 21:47:34 +0000124 if (signature_info == (SignatureInfo *) NULL)
125 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
126 (void) ResetMagickMemory(signature_info,0,sizeof(*signature_info));
127 signature_info->digestsize=SignatureDigestsize;
128 signature_info->blocksize=SignatureBlocksize;
129 signature_info->digest=AcquireStringInfo(SignatureDigestsize);
130 signature_info->message=AcquireStringInfo(SignatureBlocksize);
131 signature_info->accumulator=(unsigned int *) AcquireQuantumMemory(
132 SignatureBlocksize,sizeof(*signature_info->accumulator));
133 if (signature_info->accumulator == (unsigned int *) NULL)
134 ThrowFatalException(ResourceLimitFatalError,"MemoryAllocationFailed");
135 lsb_first=1;
136 signature_info->lsb_first=(int) (*(char *) &lsb_first) == 1 ? MagickTrue :
137 MagickFalse;
cristybb503372010-05-27 20:51:26 +0000138 signature_info->timestamp=(ssize_t) time(0);
cristy3ed852e2009-09-05 21:47:34 +0000139 signature_info->signature=MagickSignature;
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*/
167MagickExport SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
168{
169 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
170 assert(signature_info != (SignatureInfo *) NULL);
171 assert(signature_info->signature == MagickSignature);
172 if (signature_info->accumulator != (unsigned int *) NULL)
173 signature_info->accumulator=(unsigned int *) RelinquishMagickMemory(
174 signature_info->accumulator);
175 if (signature_info->message != (StringInfo *) NULL)
176 signature_info->message=DestroyStringInfo(signature_info->message);
177 if (signature_info->digest != (StringInfo *) NULL)
178 signature_info->digest=DestroyStringInfo(signature_info->digest);
179 signature_info->signature=(~MagickSignature);
180 signature_info=(SignatureInfo *) RelinquishMagickMemory(signature_info);
181 return(signature_info);
182}
183
184/*
185%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
186% %
187% %
188% %
189+ F i n a l i z e S i g n a t u r e %
190% %
191% %
192% %
193%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
194%
195% FinalizeSignature() finalizes the Signature message accumulator computation.
196%
197% The format of the FinalizeSignature method is:
198%
199% FinalizeSignature(SignatureInfo *signature_info)
200%
201% A description of each parameter follows:
202%
203% o signature_info: the address of a structure of type SignatureInfo.
204%
205*/
206MagickExport void FinalizeSignature(SignatureInfo *signature_info)
207{
cristybb503372010-05-27 20:51:26 +0000208 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000209 i;
210
211 register unsigned char
212 *q;
213
214 register unsigned int
215 *p;
216
217 unsigned char
218 *datum;
219
220 unsigned int
221 count,
222 high_order,
223 low_order;
224
225 /*
226 Add padding and return the message accumulator.
227 */
228 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
229 assert(signature_info != (SignatureInfo *) NULL);
230 assert(signature_info->signature == MagickSignature);
231 low_order=signature_info->low_order;
232 high_order=signature_info->high_order;
233 count=((low_order >> 3) & 0x3f);
234 datum=GetStringInfoDatum(signature_info->message);
235 datum[count++]=(unsigned char) 0x80;
236 if (count <= (unsigned int) (GetStringInfoLength(signature_info->message)-8))
237 (void) ResetMagickMemory(datum+count,0,GetStringInfoLength(
238 signature_info->message)-8-count);
239 else
240 {
241 (void) ResetMagickMemory(datum+count,0,GetStringInfoLength(
242 signature_info->message)-count);
243 TransformSignature(signature_info);
244 (void) ResetMagickMemory(datum,0,GetStringInfoLength(
245 signature_info->message)-8);
246 }
247 datum[56]=(unsigned char) (high_order >> 24);
248 datum[57]=(unsigned char) (high_order >> 16);
249 datum[58]=(unsigned char) (high_order >> 8);
250 datum[59]=(unsigned char) high_order;
251 datum[60]=(unsigned char) (low_order >> 24);
252 datum[61]=(unsigned char) (low_order >> 16);
253 datum[62]=(unsigned char) (low_order >> 8);
254 datum[63]=(unsigned char) low_order;
255 TransformSignature(signature_info);
256 p=signature_info->accumulator;
257 q=GetStringInfoDatum(signature_info->digest);
258 for (i=0; i < (SignatureDigestsize/4); i++)
259 {
260 *q++=(unsigned char) ((*p >> 24) & 0xff);
261 *q++=(unsigned char) ((*p >> 16) & 0xff);
262 *q++=(unsigned char) ((*p >> 8) & 0xff);
263 *q++=(unsigned char) (*p & 0xff);
264 p++;
265 }
266 /*
267 Reset working registers.
268 */
269 count=0;
270 high_order=0;
271 low_order=0;
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*/
296MagickExport 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 == MagickSignature);
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*/
327MagickExport 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 == MagickSignature);
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*/
358MagickExport 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 == MagickSignature);
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% IntializeSignature() intializes 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*/
389MagickExport void InitializeSignature(SignatureInfo *signature_info)
390{
391 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"...");
392 assert(signature_info != (SignatureInfo *) NULL);
393 assert(signature_info->signature == MagickSignature);
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->offset=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*/
432MagickExport 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 == MagickSignature);
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)
462%
463% A description of each parameter follows:
464%
465% o image: the image.
466%
467*/
468MagickExport MagickBooleanType SignatureImage(Image *image)
469{
cristyc4c8d132010-01-07 01:58:38 +0000470 CacheView
471 *image_view;
472
cristy3ed852e2009-09-05 21:47:34 +0000473 char
474 *hex_signature;
475
476 ExceptionInfo
477 *exception;
478
cristybb503372010-05-27 20:51:26 +0000479 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000480 y;
481
482 QuantumInfo
483 *quantum_info;
484
485 QuantumType
486 quantum_type;
487
488 register const PixelPacket
489 *p;
490
491 SignatureInfo
492 *signature_info;
493
494 size_t
495 length;
496
497 StringInfo
498 *signature;
499
500 unsigned char
501 *pixels;
502
cristy3ed852e2009-09-05 21:47:34 +0000503 /*
504 Compute image digital signature.
505 */
506 assert(image != (Image *) NULL);
507 assert(image->signature == MagickSignature);
508 if (image->debug != MagickFalse)
509 (void) LogMagickEvent(TraceEvent,GetMagickModule(),"%s",image->filename);
510 quantum_info=AcquireQuantumInfo((const ImageInfo *) NULL,image);
511 if (quantum_info == (QuantumInfo *) NULL)
512 ThrowBinaryException(ResourceLimitError,"MemoryAllocationFailed",
513 image->filename);
514 quantum_type=RGBQuantum;
515 if (image->matte != MagickFalse)
516 quantum_type=RGBAQuantum;
517 if (image->colorspace == CMYKColorspace)
518 {
519 quantum_type=CMYKQuantum;
520 if (image->matte != MagickFalse)
521 quantum_type=CMYKAQuantum;
522 }
523 signature_info=AcquireSignatureInfo();
524 signature=AcquireStringInfo(quantum_info->extent);
525 pixels=GetQuantumPixels(quantum_info);
526 exception=(&image->exception);
527 image_view=AcquireCacheView(image);
cristybb503372010-05-27 20:51:26 +0000528 for (y=0; y < (ssize_t) image->rows; y++)
cristy3ed852e2009-09-05 21:47:34 +0000529 {
530 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
531 if (p == (const PixelPacket *) NULL)
532 break;
533 length=ExportQuantumPixels(image,image_view,quantum_info,quantum_type,
534 pixels,&image->exception);
535 SetStringInfoLength(signature,length);
536 SetStringInfoDatum(signature,pixels);
537 UpdateSignature(signature_info,signature);
538 }
539 image_view=DestroyCacheView(image_view);
540 quantum_info=DestroyQuantumInfo(quantum_info);
541 FinalizeSignature(signature_info);
542 hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
543 (void) DeleteImageProperty(image,"signature");
544 (void) SetImageProperty(image,"signature",hex_signature);
545 /*
546 Free resources.
547 */
548 hex_signature=DestroyString(hex_signature);
549 signature=DestroyStringInfo(signature);
550 signature_info=DestroySignatureInfo(signature_info);
551 return(MagickTrue);
552}
553
554/*
555%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
556% %
557% %
558% %
559+ T r a n s f o r m S i g n a t u r e %
560% %
561% %
562% %
563%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
564%
565% TransformSignature() transforms the Signature message accumulator.
566%
567% The format of the TransformSignature method is:
568%
569% TransformSignature(SignatureInfo *signature_info)
570%
571% A description of each parameter follows:
572%
573% o signature_info: the address of a structure of type SignatureInfo.
574%
575*/
576
577static inline unsigned int Ch(unsigned int x,unsigned int y,unsigned int z)
578{
579 return((x & y) ^ (~x & z));
580}
581
582static inline unsigned int Maj(unsigned int x,unsigned int y,unsigned int z)
583{
584 return((x & y) ^ (x & z) ^ (y & z));
585}
586
587static inline unsigned int Trunc32(unsigned int x)
588{
589 return((unsigned int) (x & 0xffffffffU));
590}
591
592static unsigned int RotateRight(unsigned int x,unsigned int n)
593{
594 return(Trunc32((x >> n) | (x << (32-n))));
595}
596
597static void TransformSignature(SignatureInfo *signature_info)
598{
599#define Sigma0(x) (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
600#define Sigma1(x) (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
601#define Suma0(x) (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
602#define Suma1(x) (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
603
cristybb503372010-05-27 20:51:26 +0000604 ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000605 j;
606
cristybb503372010-05-27 20:51:26 +0000607 register ssize_t
cristy3ed852e2009-09-05 21:47:34 +0000608 i;
609
610 register unsigned char
611 *p;
612
613 static 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,
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 {
650 if (sizeof(unsigned int) <= 4)
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 if (sizeof(unsigned int) <= 4)
668 for (i=0; i < 16; i++)
669 {
670 T=(*((unsigned int *) p));
671 p+=4;
672 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
673 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
674 }
675 else
676 for (i=0; i < 16; i+=2)
677 {
678 T=(*((unsigned int *) p));
679 p+=8;
680 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
681 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
682 T>>=shift;
683 W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
684 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
685 }
686 /*
687 Copy accumulator to registers.
688 */
689 A=signature_info->accumulator[0];
690 B=signature_info->accumulator[1];
691 C=signature_info->accumulator[2];
692 D=signature_info->accumulator[3];
693 E=signature_info->accumulator[4];
694 F=signature_info->accumulator[5];
695 G=signature_info->accumulator[6];
696 H=signature_info->accumulator[7];
697 for (i=16; i < 64; i++)
698 W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
699 for (j=0; j < 64; j++)
700 {
701 T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
702 T2=Trunc32(Suma0(A)+Maj(A,B,C));
703 H=G;
704 G=F;
705 F=E;
706 E=Trunc32(D+T1);
707 D=C;
708 C=B;
709 B=A;
710 A=Trunc32(T1+T2);
711 }
712 /*
713 Add registers back to accumulator.
714 */
715 signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
716 signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
717 signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
718 signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
719 signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
720 signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
721 signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
722 signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
723 /*
724 Reset working registers.
725 */
726 A=0;
727 B=0;
728 C=0;
729 D=0;
730 E=0;
731 F=0;
732 G=0;
733 H=0;
734 T=0;
735 T1=0;
736 T2=0;
737 (void) ResetMagickMemory(W,0,sizeof(W));
738}
739
740/*
741%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
742% %
743% %
744% %
745+ U p d a t e S i g n a t u r e %
746% %
747% %
748% %
749%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
750%
751% UpdateSignature() updates the Signature message accumulator.
752%
753% The format of the UpdateSignature method is:
754%
755% UpdateSignature(SignatureInfo *signature_info,const StringInfo *message)
756%
757% A description of each parameter follows:
758%
759% o signature_info: the address of a structure of type SignatureInfo.
760%
761% o message: the message.
762%
763*/
764MagickExport void UpdateSignature(SignatureInfo *signature_info,
765 const StringInfo *message)
766{
767 register size_t
768 i;
769
770 register unsigned char
771 *p;
772
773 size_t
774 n;
775
776 unsigned int
777 length;
778
779 /*
780 Update the Signature accumulator.
781 */
782 assert(signature_info != (SignatureInfo *) NULL);
783 assert(signature_info->signature == MagickSignature);
784 n=GetStringInfoLength(message);
785 length=Trunc32((unsigned int) (signature_info->low_order+(n << 3)));
786 if (length < signature_info->low_order)
787 signature_info->high_order++;
788 signature_info->low_order=length;
789 signature_info->high_order+=(unsigned int) (n >> 29);
790 p=GetStringInfoDatum(message);
791 if (signature_info->offset != 0)
792 {
793 i=GetStringInfoLength(signature_info->message)-signature_info->offset;
794 if (i > n)
795 i=n;
796 (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message)+
797 signature_info->offset,p,i);
798 n-=i;
799 p+=i;
800 signature_info->offset+=i;
801 if (signature_info->offset !=
802 GetStringInfoLength(signature_info->message))
803 return;
804 TransformSignature(signature_info);
805 }
806 while (n >= GetStringInfoLength(signature_info->message))
807 {
808 SetStringInfoDatum(signature_info->message,p);
809 p+=GetStringInfoLength(signature_info->message);
810 n-=GetStringInfoLength(signature_info->message);
811 TransformSignature(signature_info);
812 }
813 (void) CopyMagickMemory(GetStringInfoDatum(signature_info->message),p,n);
814 signature_info->offset=n;
815 /*
816 Reset working registers.
817 */
818 i=0;
819 n=0;
820 length=0;
821}