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"
58#define SignatureBlocksize 64
59#define SignatureDigestsize 32
124 signature_info=(
SignatureInfo *) AcquireMagickMemory(
sizeof(*signature_info));
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));
139 signature_info->lsb_first=(int) (*(
char *) &lsb_first) == 1 ? MagickTrue :
141 signature_info->timestamp=GetMagickTime();
142 signature_info->signature=MagickCoreSignature;
143 InitializeSignature(signature_info);
144 return(signature_info);
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);
210MagickExport
void FinalizeSignature(
SignatureInfo *signature_info)
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);
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);
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++)
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);
297MagickExport
unsigned int GetSignatureBlocksize(
301 assert(signature_info->signature == MagickCoreSignature);
302 if (IsEventLogging() != MagickFalse)
303 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
304 return(signature_info->blocksize);
329MagickExport
const StringInfo *GetSignatureDigest(
333 assert(signature_info->signature == MagickCoreSignature);
334 if (IsEventLogging() != MagickFalse)
335 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
336 return(signature_info->digest);
361MagickExport
unsigned int GetSignatureDigestsize(
365 assert(signature_info->signature == MagickCoreSignature);
366 if (IsEventLogging() != MagickFalse)
367 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
368 return(signature_info->digestsize);
393MagickExport
void InitializeSignature(
SignatureInfo *signature_info)
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;
437MagickExport
void SetSignatureDigest(
SignatureInfo *signature_info,
444 assert(signature_info->signature == MagickCoreSignature);
445 SetStringInfo(signature_info->digest,digest);
473MagickExport MagickBooleanType SignatureImage(
Image *image)
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);
518 ThrowBinaryException(ResourceLimitError,
"MemoryAllocationFailed",
520 quantum_type=RGBQuantum;
521 if (image->matte != MagickFalse)
522 quantum_type=RGBAQuantum;
523 if (image->colorspace == CMYKColorspace)
525 quantum_type=CMYKQuantum;
526 if (image->matte != MagickFalse)
527 quantum_type=CMYKAQuantum;
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++)
535 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
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);
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);
553 hex_signature=DestroyString(hex_signature);
554 signature=DestroyStringInfo(signature);
555 signature_info=DestroySignatureInfo(signature_info);
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))
601 static const unsigned int
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
635 p=GetStringInfoDatum(signature_info->message);
636 if (signature_info->lsb_first == MagickFalse)
638DisableMSCWarning(4127)
639 if (sizeof(
unsigned int) <= 4)
641 for (i=0; i < 16; i++)
643 T=(*((
unsigned int *) p));
648 for (i=0; i < 16; i+=2)
650 T=(*((
unsigned int *) p));
652 W[i]=Trunc32(T >> shift);
657DisableMSCWarning(4127)
658 if (sizeof(
unsigned int) <= 4)
660 for (i=0; i < 16; i++)
662 T=(*((
unsigned int *) p));
664 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
665 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
668 for (i=0; i < 16; i+=2)
670 T=(*((
unsigned int *) p));
672 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
673 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
675 W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
676 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
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++)
693 T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
694 T2=Trunc32(Suma0(A)+Maj(A,B,C));
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);
729 (void) ResetMagickMemory(W,0,
sizeof(W));
756MagickExport
void UpdateSignature(
SignatureInfo *signature_info,
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)
785 i=GetStringInfoLength(signature_info->message)-signature_info->extent;
788 (void) memcpy(GetStringInfoDatum(signature_info->message)+
789 signature_info->extent,p,i);
792 signature_info->extent+=i;
793 if (signature_info->extent !=
794 GetStringInfoLength(signature_info->message))
796 TransformSignature(signature_info);
798 while (n >= GetStringInfoLength(signature_info->message))
800 SetStringInfoDatum(signature_info->message,p);
801 p+=(ptrdiff_t) GetStringInfoLength(signature_info->message);
802 n-=GetStringInfoLength(signature_info->message);
803 TransformSignature(signature_info);
805 (void) memcpy(GetStringInfoDatum(signature_info->message),p,n);
806 signature_info->extent=n;