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