Coverage Report

Created: 2025-11-14 07:32

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