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"
60#define SignatureBlocksize 64
61#define SignatureDigestsize 32
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));
140 signature_info->lsb_first=(int) (*(
char *) &lsb_first) == 1 ? MagickTrue :
142 signature_info->timestamp=GetMagickTime();
143 signature_info->signature=MagickCoreSignature;
144 InitializeSignature(signature_info);
145 return(signature_info);
174 assert(signature_info->signature == MagickCoreSignature);
175 if (IsEventLogging() != MagickFalse)
176 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
177 if (signature_info->accumulator != (
unsigned int *) NULL)
178 signature_info->accumulator=(
unsigned int *) RelinquishMagickMemory(
179 signature_info->accumulator);
180 if (signature_info->message != (
StringInfo *) NULL)
181 signature_info->message=DestroyStringInfo(signature_info->message);
182 if (signature_info->digest != (
StringInfo *) NULL)
183 signature_info->digest=DestroyStringInfo(signature_info->digest);
184 signature_info->signature=(~MagickCoreSignature);
185 signature_info=(
SignatureInfo *) RelinquishMagickMemory(signature_info);
186 return(signature_info);
211MagickPrivate
void FinalizeSignature(
SignatureInfo *signature_info)
236 assert(signature_info->signature == MagickCoreSignature);
237 if (IsEventLogging() != MagickFalse)
238 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
239 low_order=signature_info->low_order;
240 high_order=signature_info->high_order;
241 extent=((low_order >> 3) & 0x3f);
242 datum=GetStringInfoDatum(signature_info->message);
243 datum[extent++]=(
unsigned char) 0x80;
244 if (extent <= (
unsigned int) (GetStringInfoLength(signature_info->message)-8))
245 (void) memset(datum+extent,0,GetStringInfoLength(
246 signature_info->message)-8-extent);
249 (void) memset(datum+extent,0,GetStringInfoLength(
250 signature_info->message)-extent);
251 TransformSignature(signature_info);
252 (void) memset(datum,0,GetStringInfoLength(
253 signature_info->message)-8);
255 datum[56]=(
unsigned char) (high_order >> 24);
256 datum[57]=(
unsigned char) (high_order >> 16);
257 datum[58]=(
unsigned char) (high_order >> 8);
258 datum[59]=(
unsigned char) high_order;
259 datum[60]=(
unsigned char) (low_order >> 24);
260 datum[61]=(
unsigned char) (low_order >> 16);
261 datum[62]=(
unsigned char) (low_order >> 8);
262 datum[63]=(
unsigned char) low_order;
263 TransformSignature(signature_info);
264 p=signature_info->accumulator;
265 q=GetStringInfoDatum(signature_info->digest);
266 for (i=0; i < (SignatureDigestsize/4); i++)
268 *q++=(
unsigned char) ((*p >> 24) & 0xff);
269 *q++=(
unsigned char) ((*p >> 16) & 0xff);
270 *q++=(
unsigned char) ((*p >> 8) & 0xff);
271 *q++=(
unsigned char) (*p & 0xff);
298MagickPrivate
unsigned int GetSignatureBlocksize(
302 assert(signature_info->signature == MagickCoreSignature);
303 if (IsEventLogging() != MagickFalse)
304 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
305 return(signature_info->blocksize);
330MagickPrivate
const StringInfo *GetSignatureDigest(
334 assert(signature_info->signature == MagickCoreSignature);
335 if (IsEventLogging() != MagickFalse)
336 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
337 return(signature_info->digest);
362MagickPrivate
unsigned int GetSignatureDigestsize(
366 assert(signature_info->signature == MagickCoreSignature);
367 if (IsEventLogging() != MagickFalse)
368 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
369 return(signature_info->digestsize);
394MagickPrivate
void InitializeSignature(
SignatureInfo *signature_info)
397 assert(signature_info->signature == MagickCoreSignature);
398 if (IsEventLogging() != MagickFalse)
399 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
400 signature_info->accumulator[0]=0x6a09e667U;
401 signature_info->accumulator[1]=0xbb67ae85U;
402 signature_info->accumulator[2]=0x3c6ef372U;
403 signature_info->accumulator[3]=0xa54ff53aU;
404 signature_info->accumulator[4]=0x510e527fU;
405 signature_info->accumulator[5]=0x9b05688cU;
406 signature_info->accumulator[6]=0x1f83d9abU;
407 signature_info->accumulator[7]=0x5be0cd19U;
408 signature_info->low_order=0;
409 signature_info->high_order=0;
410 signature_info->extent=0;
438MagickPrivate
void SetSignatureDigest(
SignatureInfo *signature_info,
445 assert(signature_info->signature == MagickCoreSignature);
446 SetStringInfo(signature_info->digest,digest);
476MagickExport MagickBooleanType SignatureImage(
Image *image,
506 assert(image != (
Image *) NULL);
507 assert(image->signature == MagickCoreSignature);
508 if (IsEventLogging() != MagickFalse)
509 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
510 signature_info=AcquireSignatureInfo();
511 signature=AcquireStringInfo(GetPixelChannels(image)*image->columns*
513 image_view=AcquireVirtualCacheView(image,exception);
514 for (y=0; y < (ssize_t) image->rows; y++)
522 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
523 if (p == (
const Quantum *) NULL)
525 SetStringInfoLength(signature,GetPixelChannels(image)*image->columns*
527 pixels=GetStringInfoDatum(signature);
529 for (x=0; x < (ssize_t) image->columns; x++)
534 if (GetPixelReadMask(image,p) <= (QuantumRange/2))
536 p+=(ptrdiff_t) GetPixelChannels(image);
539 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
544 PixelChannel channel = GetPixelChannelChannel(image,i);
545 PixelTrait traits = GetPixelChannelTraits(image,channel);
546 if ((traits & UpdatePixelTrait) == 0)
548 pixel=(float) (QuantumScale*(
double) p[i]);
549 if (signature_info->lsb_first == MagickFalse)
550 for (j=(ssize_t)
sizeof(pixel)-1; j >= 0; j--)
551 *q++=(
unsigned char) ((
unsigned char *) &pixel)[j];
553 for (j=0; j < (ssize_t)
sizeof(pixel); j++)
554 *q++=(
unsigned char) ((
unsigned char *) &pixel)[j];
556 p+=(ptrdiff_t) GetPixelChannels(image);
558 SetStringInfoLength(signature,(
size_t) (q-pixels));
559 UpdateSignature(signature_info,signature);
561 image_view=DestroyCacheView(image_view);
562 FinalizeSignature(signature_info);
563 hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
564 (void) DeleteImageProperty(image,
"signature");
565 (void) SetImageProperty(image,
"signature",hex_signature,exception);
569 hex_signature=DestroyString(hex_signature);
570 signature=DestroyStringInfo(signature);
571 signature_info=DestroySignatureInfo(signature_info);
599#define Ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
600#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
601#define RotateRight(x,n) (Trunc32(((x) >> n) | ((x) << (32-n))))
602#define Sigma0(x) (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
603#define Sigma1(x) (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
604#define Suma0(x) (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
605#define Suma1(x) (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
606#define Trunc32(x) ((unsigned int) ((x) & 0xffffffffU))
617 static const unsigned int
620 0x428a2f98U, 0x71374491U, 0xb5c0fbcfU, 0xe9b5dba5U, 0x3956c25bU,
621 0x59f111f1U, 0x923f82a4U, 0xab1c5ed5U, 0xd807aa98U, 0x12835b01U,
622 0x243185beU, 0x550c7dc3U, 0x72be5d74U, 0x80deb1feU, 0x9bdc06a7U,
623 0xc19bf174U, 0xe49b69c1U, 0xefbe4786U, 0x0fc19dc6U, 0x240ca1ccU,
624 0x2de92c6fU, 0x4a7484aaU, 0x5cb0a9dcU, 0x76f988daU, 0x983e5152U,
625 0xa831c66dU, 0xb00327c8U, 0xbf597fc7U, 0xc6e00bf3U, 0xd5a79147U,
626 0x06ca6351U, 0x14292967U, 0x27b70a85U, 0x2e1b2138U, 0x4d2c6dfcU,
627 0x53380d13U, 0x650a7354U, 0x766a0abbU, 0x81c2c92eU, 0x92722c85U,
628 0xa2bfe8a1U, 0xa81a664bU, 0xc24b8b70U, 0xc76c51a3U, 0xd192e819U,
629 0xd6990624U, 0xf40e3585U, 0x106aa070U, 0x19a4c116U, 0x1e376c08U,
630 0x2748774cU, 0x34b0bcb5U, 0x391c0cb3U, 0x4ed8aa4aU, 0x5b9cca4fU,
631 0x682e6ff3U, 0x748f82eeU, 0x78a5636fU, 0x84c87814U, 0x8cc70208U,
632 0x90befffaU, 0xa4506cebU, 0xbef9a3f7U, 0xc67178f2U
651 p=GetStringInfoDatum(signature_info->message);
652 if (signature_info->lsb_first == MagickFalse)
654DisableMSCWarning(4127)
655 if (sizeof(
unsigned int) <= 4)
657 for (i=0; i < 16; i++)
659 T=(*((
unsigned int *) p));
664 for (i=0; i < 16; i+=2)
666 T=(*((
unsigned int *) p));
668 W[i]=Trunc32(T >> shift);
673DisableMSCWarning(4127)
674 if (sizeof(
unsigned int) <= 4)
676 for (i=0; i < 16; i++)
678 T=(*((
unsigned int *) p));
680 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
681 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
684 for (i=0; i < 16; i+=2)
686 T=(*((
unsigned int *) p));
688 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
689 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
691 W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
692 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
697 A=signature_info->accumulator[0];
698 B=signature_info->accumulator[1];
699 C=signature_info->accumulator[2];
700 D=signature_info->accumulator[3];
701 E=signature_info->accumulator[4];
702 F=signature_info->accumulator[5];
703 G=signature_info->accumulator[6];
704 H=signature_info->accumulator[7];
705 for (i=16; i < 64; i++)
706 W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
707 for (j=0; j < 64; j++)
709 T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
710 T2=Trunc32(Suma0(A)+Maj(A,B,C));
723 signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
724 signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
725 signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
726 signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
727 signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
728 signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
729 signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
730 signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
745 (void) ResetMagickMemory(W,0,
sizeof(W));
772MagickPrivate
void UpdateSignature(
SignatureInfo *signature_info,
791 assert(signature_info->signature == MagickCoreSignature);
792 n=GetStringInfoLength(message);
793 length=Trunc32((
unsigned int) (signature_info->low_order+(n << 3)));
794 if (length < signature_info->low_order)
795 signature_info->high_order++;
796 signature_info->low_order=length;
797 signature_info->high_order+=(
unsigned int) n >> 29;
798 p=GetStringInfoDatum(message);
799 if (signature_info->extent != 0)
801 i=GetStringInfoLength(signature_info->message)-signature_info->extent;
804 (void) memcpy(GetStringInfoDatum(signature_info->message)+
805 signature_info->extent,p,i);
808 signature_info->extent+=i;
809 if (signature_info->extent != GetStringInfoLength(signature_info->message))
811 TransformSignature(signature_info);
813 while (n >= GetStringInfoLength(signature_info->message))
815 SetStringInfoDatum(signature_info->message,p);
816 p+=(ptrdiff_t) GetStringInfoLength(signature_info->message);
817 n-=GetStringInfoLength(signature_info->message);
818 TransformSignature(signature_info);
820 (void) memcpy(GetStringInfoDatum(signature_info->message),p,n);
821 signature_info->extent=n;