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
98 TransformSignature(SignatureInfo *);
118MagickPrivate SignatureInfo *AcquireSignatureInfo(
void)
123 signature_info=(SignatureInfo *) AcquireCriticalMemory(
124 sizeof(*signature_info));
125 (void) memset(signature_info,0,
sizeof(*signature_info));
126 signature_info->digestsize=SignatureDigestsize;
127 signature_info->blocksize=SignatureBlocksize;
128 signature_info->digest=AcquireStringInfo(SignatureDigestsize);
129 signature_info->message=AcquireStringInfo(SignatureBlocksize);
130 signature_info->accumulator=(
unsigned int *) AcquireQuantumMemory(
131 SignatureBlocksize,
sizeof(*signature_info->accumulator));
132 if (signature_info->accumulator == (
unsigned int *) NULL)
133 ThrowFatalException(ResourceLimitFatalError,
"MemoryAllocationFailed");
134 (void) memset(signature_info->accumulator,0,SignatureBlocksize*
135 sizeof(*signature_info->accumulator));
136 signature_info->lsb_first=GetHostEndian() == LSBEndian ? MagickTrue :
138 signature_info->timestamp=GetMagickTime();
139 signature_info->signature=MagickCoreSignature;
140 InitializeSignature(signature_info);
141 return(signature_info);
167MagickPrivate SignatureInfo *DestroySignatureInfo(SignatureInfo *signature_info)
169 assert(signature_info != (SignatureInfo *) NULL);
170 assert(signature_info->signature == MagickCoreSignature);
171 if (IsEventLogging() != MagickFalse)
172 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
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);
207MagickPrivate
void FinalizeSignature(SignatureInfo *signature_info)
231 assert(signature_info != (SignatureInfo *) NULL);
232 assert(signature_info->signature == MagickCoreSignature);
233 if (IsEventLogging() != MagickFalse)
234 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
235 low_order=signature_info->low_order;
236 high_order=signature_info->high_order;
237 extent=((low_order >> 3) & 0x3f);
238 datum=GetStringInfoDatum(signature_info->message);
239 datum[extent++]=(
unsigned char) 0x80;
240 if (extent <= (
unsigned int) (GetStringInfoLength(signature_info->message)-8))
241 (void) memset(datum+extent,0,GetStringInfoLength(
242 signature_info->message)-8-extent);
245 (void) memset(datum+extent,0,GetStringInfoLength(
246 signature_info->message)-extent);
247 TransformSignature(signature_info);
248 (void) memset(datum,0,GetStringInfoLength(
249 signature_info->message)-8);
251 datum[56]=(
unsigned char) (high_order >> 24);
252 datum[57]=(
unsigned char) (high_order >> 16);
253 datum[58]=(
unsigned char) (high_order >> 8);
254 datum[59]=(
unsigned char) high_order;
255 datum[60]=(
unsigned char) (low_order >> 24);
256 datum[61]=(
unsigned char) (low_order >> 16);
257 datum[62]=(
unsigned char) (low_order >> 8);
258 datum[63]=(
unsigned char) low_order;
259 TransformSignature(signature_info);
260 p=signature_info->accumulator;
261 q=GetStringInfoDatum(signature_info->digest);
262 for (i=0; i < (SignatureDigestsize/4); i++)
264 *q++=(
unsigned char) ((*p >> 24) & 0xff);
265 *q++=(
unsigned char) ((*p >> 16) & 0xff);
266 *q++=(
unsigned char) ((*p >> 8) & 0xff);
267 *q++=(
unsigned char) (*p & 0xff);
294MagickPrivate
unsigned int GetSignatureBlocksize(
295 const SignatureInfo *signature_info)
297 assert(signature_info != (SignatureInfo *) NULL);
298 assert(signature_info->signature == MagickCoreSignature);
299 if (IsEventLogging() != MagickFalse)
300 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
301 return(signature_info->blocksize);
326MagickPrivate
const StringInfo *GetSignatureDigest(
327 const SignatureInfo *signature_info)
329 assert(signature_info != (SignatureInfo *) NULL);
330 assert(signature_info->signature == MagickCoreSignature);
331 if (IsEventLogging() != MagickFalse)
332 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
333 return(signature_info->digest);
358MagickPrivate
unsigned int GetSignatureDigestsize(
359 const SignatureInfo *signature_info)
361 assert(signature_info != (SignatureInfo *) NULL);
362 assert(signature_info->signature == MagickCoreSignature);
363 if (IsEventLogging() != MagickFalse)
364 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
365 return(signature_info->digestsize);
390MagickPrivate
void InitializeSignature(SignatureInfo *signature_info)
392 assert(signature_info != (SignatureInfo *) NULL);
393 assert(signature_info->signature == MagickCoreSignature);
394 if (IsEventLogging() != MagickFalse)
395 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"...");
396 signature_info->accumulator[0]=0x6a09e667U;
397 signature_info->accumulator[1]=0xbb67ae85U;
398 signature_info->accumulator[2]=0x3c6ef372U;
399 signature_info->accumulator[3]=0xa54ff53aU;
400 signature_info->accumulator[4]=0x510e527fU;
401 signature_info->accumulator[5]=0x9b05688cU;
402 signature_info->accumulator[6]=0x1f83d9abU;
403 signature_info->accumulator[7]=0x5be0cd19U;
404 signature_info->low_order=0;
405 signature_info->high_order=0;
406 signature_info->extent=0;
434MagickPrivate
void SetSignatureDigest(SignatureInfo *signature_info,
435 const StringInfo *digest)
440 assert(signature_info != (SignatureInfo *) NULL);
441 assert(signature_info->signature == MagickCoreSignature);
442 SetStringInfo(signature_info->digest,digest);
472MagickExport MagickBooleanType SignatureImage(Image *image,
473 ExceptionInfo *exception)
502 assert(image != (Image *) NULL);
503 assert(image->signature == MagickCoreSignature);
504 if (IsEventLogging() != MagickFalse)
505 (void) LogMagickEvent(TraceEvent,GetMagickModule(),
"%s",image->filename);
506 signature_info=AcquireSignatureInfo();
507 signature=AcquireStringInfo(GetPixelChannels(image)*image->columns*
509 image_view=AcquireVirtualCacheView(image,exception);
510 for (y=0; y < (ssize_t) image->rows; y++)
518 p=GetCacheViewVirtualPixels(image_view,0,y,image->columns,1,exception);
519 if (p == (
const Quantum *) NULL)
521 SetStringInfoLength(signature,GetPixelChannels(image)*image->columns*
523 pixels=GetStringInfoDatum(signature);
525 for (x=0; x < (ssize_t) image->columns; x++)
530 if (GetPixelReadMask(image,p) <= (QuantumRange/2))
532 p+=(ptrdiff_t) GetPixelChannels(image);
535 for (i=0; i < (ssize_t) GetPixelChannels(image); i++)
540 PixelChannel channel = GetPixelChannelChannel(image,i);
541 PixelTrait traits = GetPixelChannelTraits(image,channel);
542 if ((traits & UpdatePixelTrait) == 0)
544 pixel=(float) (QuantumScale*(
double) p[i]);
545 if (signature_info->lsb_first == MagickFalse)
546 for (j=(ssize_t)
sizeof(pixel)-1; j >= 0; j--)
547 *q++=(
unsigned char) ((
unsigned char *) &pixel)[j];
549 for (j=0; j < (ssize_t)
sizeof(pixel); j++)
550 *q++=(
unsigned char) ((
unsigned char *) &pixel)[j];
552 p+=(ptrdiff_t) GetPixelChannels(image);
554 SetStringInfoLength(signature,(
size_t) (q-pixels));
555 UpdateSignature(signature_info,signature);
557 image_view=DestroyCacheView(image_view);
558 FinalizeSignature(signature_info);
559 hex_signature=StringInfoToHexString(GetSignatureDigest(signature_info));
560 (void) DeleteImageProperty(image,
"signature");
561 (void) SetImageProperty(image,
"signature",hex_signature,exception);
565 hex_signature=DestroyString(hex_signature);
566 signature=DestroyStringInfo(signature);
567 signature_info=DestroySignatureInfo(signature_info);
593static void TransformSignature(SignatureInfo *signature_info)
595#define Ch(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
596#define Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
597#define RotateRight(x,n) (Trunc32(((x) >> n) | ((x) << (32-n))))
598#define Sigma0(x) (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
599#define Sigma1(x) (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
600#define Suma0(x) (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
601#define Suma1(x) (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
602#define Trunc32(x) ((unsigned int) ((x) & 0xffffffffU))
613 static const unsigned int
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
647 p=GetStringInfoDatum(signature_info->message);
648 if (signature_info->lsb_first == MagickFalse)
650DisableMSCWarning(4127)
651 if (sizeof(
unsigned int) <= 4)
653 for (i=0; i < 16; i++)
655 T=(*((
unsigned int *) p));
660 for (i=0; i < 16; i+=2)
662 T=(*((
unsigned int *) p));
664 W[i]=Trunc32(T >> shift);
669DisableMSCWarning(4127)
670 if (sizeof(
unsigned int) <= 4)
672 for (i=0; i < 16; i++)
674 T=(*((
unsigned int *) p));
676 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
677 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
680 for (i=0; i < 16; i+=2)
682 T=(*((
unsigned int *) p));
684 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
685 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
687 W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
688 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
693 A=signature_info->accumulator[0];
694 B=signature_info->accumulator[1];
695 C=signature_info->accumulator[2];
696 D=signature_info->accumulator[3];
697 E=signature_info->accumulator[4];
698 F=signature_info->accumulator[5];
699 G=signature_info->accumulator[6];
700 H=signature_info->accumulator[7];
701 for (i=16; i < 64; i++)
702 W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
703 for (j=0; j < 64; j++)
705 T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
706 T2=Trunc32(Suma0(A)+Maj(A,B,C));
719 signature_info->accumulator[0]=Trunc32(signature_info->accumulator[0]+A);
720 signature_info->accumulator[1]=Trunc32(signature_info->accumulator[1]+B);
721 signature_info->accumulator[2]=Trunc32(signature_info->accumulator[2]+C);
722 signature_info->accumulator[3]=Trunc32(signature_info->accumulator[3]+D);
723 signature_info->accumulator[4]=Trunc32(signature_info->accumulator[4]+E);
724 signature_info->accumulator[5]=Trunc32(signature_info->accumulator[5]+F);
725 signature_info->accumulator[6]=Trunc32(signature_info->accumulator[6]+G);
726 signature_info->accumulator[7]=Trunc32(signature_info->accumulator[7]+H);
741 (void) ResetMagickMemory(W,0,
sizeof(W));
768MagickPrivate
void UpdateSignature(SignatureInfo *signature_info,
769 const StringInfo *message)
786 assert(signature_info != (SignatureInfo *) NULL);
787 assert(signature_info->signature == MagickCoreSignature);
788 n=GetStringInfoLength(message);
789 length=Trunc32((
unsigned int) (signature_info->low_order+(n << 3)));
790 if (length < signature_info->low_order)
791 signature_info->high_order++;
792 signature_info->low_order=length;
793 signature_info->high_order+=(
unsigned int) n >> 29;
794 p=GetStringInfoDatum(message);
795 if (signature_info->extent != 0)
797 i=GetStringInfoLength(signature_info->message)-signature_info->extent;
800 (void) memcpy(GetStringInfoDatum(signature_info->message)+
801 signature_info->extent,p,i);
804 signature_info->extent+=i;
805 if (signature_info->extent != GetStringInfoLength(signature_info->message))
807 TransformSignature(signature_info);
809 while (n >= GetStringInfoLength(signature_info->message))
811 SetStringInfoDatum(signature_info->message,p);
812 p+=(ptrdiff_t) GetStringInfoLength(signature_info->message);
813 n-=GetStringInfoLength(signature_info->message);
814 TransformSignature(signature_info);
816 (void) memcpy(GetStringInfoDatum(signature_info->message),p,n);
817 signature_info->extent=n;