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