MagickCore 7.0.10
sha1.c
Go to the documentation of this file.
1/*
2%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3% %
4% %
5% SSSSS H H AAA %
6% SS H H A A %
7% SSS HHHHH AAAAA %
8% SS H H A A %
9% SSSSS H H A A %
10% %
11% %
12% Wizard's Toolkit Secure Hash Algorithm 1 Methods %
13% %
14% Software Design %
15% Cristy %
16% March 2003 %
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% See http://csrc.nist.gov/groups/ST/toolkit/index.html
36%
37*/
38
39/*
40 Include declarations.
41*/
42#include "wizard/studio.h"
43#include "wizard/exception.h"
45#include "wizard/memory_.h"
46#include "wizard/sha1.h"
47
48/*
49 Define declarations.
50*/
51#define SHA1Blocksize 64
52#define SHA1Digestsize 20
53
54/*
55 Typedef declarations.
56*/
58{
59 unsigned int
62
66
67 unsigned int
71
72 size_t
74
77
78 time_t
80
81 size_t
83};
84
85/*
86 Forward declarations.
87*/
88static void
90
91/*
92%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
93% %
94% %
95% %
96% A c q u i r e S H A I n f o %
97% %
98% %
99% %
100%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
101%
102% AcquireSHA1Info() allocate the SHA1Info structure.
103%
104% The format of the AcquireSHA1Info method is:
105%
106% SHA1Info *AcquireSHA1Info(void)
107%
108*/
110{
112 *sha_info;
113
114 unsigned int
115 lsb_first;
116
117 sha_info=(SHA1Info *) AcquireWizardMemory(sizeof(*sha_info));
118 if (sha_info == (SHA1Info *) NULL)
120 (void) memset(sha_info,0,sizeof(*sha_info));
121 sha_info->digestsize=SHA1Digestsize;
122 sha_info->blocksize=SHA1Blocksize;
125 sha_info->accumulator=(unsigned int *) AcquireQuantumMemory(SHA1Blocksize,
126 sizeof(*sha_info->accumulator));
127 if (sha_info->accumulator == (unsigned int *) NULL)
129 lsb_first=1;
130 sha_info->lsb_first=(int)
131 (*(char *) &lsb_first) == 1 ? WizardTrue : WizardFalse;
132 sha_info->timestamp=time((time_t *) NULL);
133 sha_info->signature=WizardSignature;
134 (void) InitializeSHA1(sha_info);
135 return(sha_info);
136}
137
138/*
139%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
140% %
141% %
142% %
143% D e s t r o y S H A I n f o %
144% %
145% %
146% %
147%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
148%
149% DestroySHA1Info() zeros memory associated with the SHA1Info structure.
150%
151% The format of the DestroySHA1Info method is:
152%
153% SHA1Info *DestroySHA1Info(SHA1Info *sha_info)
154%
155% A description of each parameter follows:
156%
157% o sha_info: The cipher sha_info.
158%
159*/
161{
163 assert(sha_info != (SHA1Info *) NULL);
164 assert(sha_info->signature == WizardSignature);
165 if (sha_info->accumulator != (unsigned int *) NULL)
166 sha_info->accumulator=(unsigned int *)
168 if (sha_info->message != (StringInfo *) NULL)
169 sha_info->message=DestroyStringInfo(sha_info->message);
170 if (sha_info->digest != (StringInfo *) NULL)
171 sha_info->digest=DestroyStringInfo(sha_info->digest);
172 sha_info->signature=(~WizardSignature);
173 sha_info=(SHA1Info *) RelinquishWizardMemory(sha_info);
174 return(sha_info);
175}
176
177/*
178%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
179% %
180% %
181% %
182% F i n a l i z e S H A %
183% %
184% %
185% %
186%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
187%
188% FinalizeSHA1() finalizes the SHA1 message accumulator computation.
189%
190% The format of the FinalizeSHA1 method is:
191%
192% WizardBooleanType FinalizeSHA1(SHA1Info *sha_info)
193%
194% A description of each parameter follows:
195%
196% o sha_info: The address of a structure of type SHA1Info.
197%
198*/
200{
201 size_t
202 i;
203
204 unsigned char
205 *q;
206
207 unsigned int
208 *p;
209
210 ssize_t
211 count;
212
213 unsigned char
214 *datum;
215
216 unsigned int
217 high_order,
218 low_order;
219
220 /*
221 Add padding and return the message accumulator.
222 */
224 assert(sha_info != (SHA1Info *) NULL);
225 assert(sha_info->signature == WizardSignature);
226 low_order=sha_info->low_order;
227 high_order=sha_info->high_order;
228 count=(ssize_t) ((low_order >> 3) & 0x3f);
229 datum=GetStringInfoDatum(sha_info->message);
230 datum[count++]=(unsigned char) 0x80;
231 if (count <= (ssize_t) (GetStringInfoLength(sha_info->message)-8))
232 (void) memset(datum+count,0,GetStringInfoLength(
233 sha_info->message)-8-count);
234 else
235 {
236 (void) memset(datum+count,0,GetStringInfoLength(
237 sha_info->message)-count);
238 TransformSHA1(sha_info);
239 (void) memset(datum,0,GetStringInfoLength(sha_info->message)-
240 8);
241 }
242 datum[56]=(unsigned char) (high_order >> 24);
243 datum[57]=(unsigned char) (high_order >> 16);
244 datum[58]=(unsigned char) (high_order >> 8);
245 datum[59]=(unsigned char) high_order;
246 datum[60]=(unsigned char) (low_order >> 24);
247 datum[61]=(unsigned char) (low_order >> 16);
248 datum[62]=(unsigned char) (low_order >> 8);
249 datum[63]=(unsigned char) low_order;
250 TransformSHA1(sha_info);
251 p=sha_info->accumulator;
252 q=GetStringInfoDatum(sha_info->digest);
253 for (i=0; i < (SHA1Digestsize/4); i++)
254 {
255 *q++=(unsigned char) ((*p >> 24) & 0xff);
256 *q++=(unsigned char) ((*p >> 16) & 0xff);
257 *q++=(unsigned char) ((*p >> 8) & 0xff);
258 *q++=(unsigned char) (*p & 0xff);
259 p++;
260 }
261 /*
262 Reset working registers.
263 */
264 count=0;
265 high_order=0;
266 low_order=0;
267 return(WizardTrue);
268}
269
270/*
271%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
272% %
273% %
274% %
275% G e t S H A 1 B l o c k s i z e %
276% %
277% %
278% %
279%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
280%
281% GetSHA1Blocksize() returns the SHA1 blocksize.
282%
283% The format of the GetSHA1Blocksize method is:
284%
285% unsigned int *GetSHA1Blocksize(const SHA1Info *sha1_info)
286%
287% A description of each parameter follows:
288%
289% o sha1_info: The sha1 info.
290%
291*/
292WizardExport unsigned int GetSHA1Blocksize(const SHA1Info *sha1_info)
293{
295 WizardAssert(CipherDomain,sha1_info != (SHA1Info *) NULL);
297 return(sha1_info->blocksize);
298}
299
300/*
301%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
302% %
303% %
304% %
305% G e t S H A 1 D i g e s t %
306% %
307% %
308% %
309%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
310%
311% GetSHA1Digest() returns the SHA1 digest.
312%
313% The format of the GetSHA1Digest method is:
314%
315% const StringInfo *GetSHA1Digest(const SHA1Info *sha1_info)
316%
317% A description of each parameter follows:
318%
319% o sha1_info: The sha1 info.
320%
321*/
323{
325 WizardAssert(HashDomain,sha1_info != (SHA1Info *) NULL);
327 return(sha1_info->digest);
328}
329
330/*
331%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
332% %
333% %
334% %
335% G e t S H A 1 D i g e s t s i z e %
336% %
337% %
338% %
339%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
340%
341% GetSHA1Digestsize() returns the SHA1 digest size.
342%
343% The format of the GetSHA1Digestsize method is:
344%
345% unsigned int *GetSHA1Digestsize(const SHA1Info *sha1_info)
346%
347% A description of each parameter follows:
348%
349% o sha1_info: The sha1 info.
350%
351*/
352WizardExport unsigned int GetSHA1Digestsize(const SHA1Info *sha1_info)
353{
355 WizardAssert(CipherDomain,sha1_info != (SHA1Info *) NULL);
357 return(sha1_info->digestsize);
358}
359
360/*
361%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
362% %
363% %
364% %
365% I n i t i a l i z e S H A %
366% %
367% %
368% %
369%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
370%
371% IntializeSHA1() intializes the SHA1 accumulator.
372%
373% The format of the DestroySHA1Info method is:
374%
375% WizardBooleanType InitializeSHA1Info(SHA1Info *sha_info)
376%
377% A description of each parameter follows:
378%
379% o sha_info: The cipher sha_info.
380%
381*/
383{
385 assert(sha_info != (SHA1Info *) NULL);
386 assert(sha_info->signature == WizardSignature);
387 sha_info->accumulator[0]=0x67452301U;
388 sha_info->accumulator[1]=0xefcdab89U;
389 sha_info->accumulator[2]=0x98badcfeU;
390 sha_info->accumulator[3]=0x10325476U;
391 sha_info->accumulator[4]=0xc3d2e1f0U;
392 sha_info->low_order=0;
393 sha_info->high_order=0;
394 sha_info->offset=0;
395 return(WizardTrue);
396}
397
398/*
399%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
400% %
401% %
402% %
403% T r a n s f o r m S H A %
404% %
405% %
406% %
407%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
408%
409% TransformSHA1() transforms the SHA1 message accumulator.
410%
411% The format of the TransformSHA1 method is:
412%
413% TransformSHA1(SHA1Info *sha_info)
414%
415% A description of each parameter follows:
416%
417% o sha_info: The address of a structure of type SHA1Info.
418%
419*/
420
421static inline unsigned int Trunc32(const unsigned int x)
422{
423 return(x & 0xffffffffU);
424}
425
426static unsigned int RotateLeft(const unsigned int x,const unsigned int n)
427{
428 return(Trunc32((x << n) | (x >> (32-n))));
429}
430
431static void TransformSHA1(SHA1Info *sha_info)
432{
433 ssize_t
434 i;
435
436 unsigned char
437 *p;
438
439 unsigned int
440 *q;
441
442 unsigned int
443 A,
444 B,
445 C,
446 D,
447 E,
448 shift,
449 T,
450 W[80];
451
452 shift=32;
453 p=GetStringInfoDatum(sha_info->message);
454 if (sha_info->lsb_first == WizardFalse)
455 {
456 if (sizeof(unsigned int) <= 4)
457 for (i=0; i < 16; i++)
458 {
459 T=(*((unsigned int *) p));
460 p+=4;
461 W[i]=Trunc32(T);
462 }
463 else
464 for (i=0; i < 16; i+=2)
465 {
466 T=(*((unsigned int *) p));
467 p+=8;
468 W[i]=Trunc32(T >> shift);
469 W[i+1]=Trunc32(T);
470 }
471 }
472 else
473 if (sizeof(unsigned int) <= 4)
474 for (i=0; i < 16; i++)
475 {
476 T=(*((unsigned int *) p));
477 p+=4;
478 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
479 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
480 }
481 else
482 for (i=0; i < 16; i+=2)
483 {
484 T=(*((unsigned int *) p));
485 p+=8;
486 W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
487 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
488 T>>=shift;
489 W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
490 ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
491 }
492 /*
493 Copy accumulator to registers.
494 */
495 A=sha_info->accumulator[0];
496 B=sha_info->accumulator[1];
497 C=sha_info->accumulator[2];
498 D=sha_info->accumulator[3];
499 E=sha_info->accumulator[4];
500 for (i=16; i < 80; i++)
501 {
502 W[i]=W[i-3] ^ W[i-8] ^ W[i-14] ^ W[i-16];
503 W[i]=RotateLeft(W[i],1);
504 }
505 q=W;
506 for (i=0; i < 20; i++)
507 {
508 T=Trunc32(RotateLeft(A,5)+((B & C) | (~B & D))+E+(*q)+0x5a827999U);
509 E=D;
510 D=C;
511 C=RotateLeft(B,30);
512 B=A;
513 A=T;
514 q++;
515 }
516 for ( ; i < 40; i++)
517 {
518 T=Trunc32(RotateLeft(A,5)+(B ^ C ^ D)+E+(*q)+0x6ed9eba1U);
519 E=D;
520 D=C;
521 C=RotateLeft(B,30);
522 B=A;
523 A=T;
524 q++;
525 }
526 for ( ; i < 60; i++)
527 {
528 T=Trunc32(RotateLeft(A,5)+((B & C) | (B & D) | (C & D))+E+(*q)+
529 0x8F1bbcdcU);
530 E=D;
531 D=C;
532 C=RotateLeft(B,30);
533 B=A;
534 A=T;
535 q++;
536 }
537 for ( ; i < 80; i++)
538 {
539 T=Trunc32(RotateLeft(A,5)+(B ^ C ^ D)+E+(*q)+0xca62c1d6U);
540 E=D;
541 D=C;
542 C=RotateLeft(B,30);
543 B=A;
544 A=T;
545 q++;
546 }
547 /*
548 Add registers back to accumulator.
549 */
550 sha_info->accumulator[0]=Trunc32(sha_info->accumulator[0]+A);
551 sha_info->accumulator[1]=Trunc32(sha_info->accumulator[1]+B);
552 sha_info->accumulator[2]=Trunc32(sha_info->accumulator[2]+C);
553 sha_info->accumulator[3]=Trunc32(sha_info->accumulator[3]+D);
554 sha_info->accumulator[4]=Trunc32(sha_info->accumulator[4]+E);
555 /*
556 Reset working registers.
557 */
558 A=0;
559 B=0;
560 C=0;
561 D=0;
562 E=0;
563 T=0;
564 (void) memset(W,0,sizeof(W));
565}
566
567/*
568%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
569% %
570% %
571% %
572% U p d a t e S H A %
573% %
574% %
575% %
576%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
577%
578% UpdateSHA1() updates the SHA1 message accumulator.
579%
580% The format of the UpdateSHA1 method is:
581%
582% WizardBooleanType UpdateSHA1(SHA1Info *sha_info,
583% const StringInfo *message)
584%
585% A description of each parameter follows:
586%
587% o sha_info: The address of a structure of type SHA1Info.
588%
589% o message: The message
590%
591*/
593 const StringInfo *message)
594{
595 size_t
596 i;
597
598 unsigned char
599 *p;
600
601 size_t
602 n;
603
604 unsigned int
605 length;
606
607 /*
608 Update the SHA1 accumulator.
609 */
610 assert(sha_info != (SHA1Info *) NULL);
611 assert(sha_info->signature == WizardSignature);
612 n=GetStringInfoLength(message);
613 length=Trunc32((unsigned int) (sha_info->low_order+(n << 3)));
614 if (length < sha_info->low_order)
615 sha_info->high_order++;
616 sha_info->low_order=length;
617 sha_info->high_order+=(unsigned int) n >> 29;
618 p=GetStringInfoDatum(message);
619 if (sha_info->offset != 0)
620 {
621 i=GetStringInfoLength(sha_info->message)-sha_info->offset;
622 if (i > n)
623 i=n;
625 sha_info->offset,p,i);
626 n-=i;
627 p+=i;
628 sha_info->offset+=i;
629 if (sha_info->offset != GetStringInfoLength(sha_info->message))
630 return(WizardTrue);
631 TransformSHA1(sha_info);
632 }
633 while (n >= GetStringInfoLength(sha_info->message))
634 {
635 SetStringInfoDatum(sha_info->message,p);
636 p+=GetStringInfoLength(sha_info->message);
637 n-=GetStringInfoLength(sha_info->message);
638 TransformSHA1(sha_info);
639 }
640 (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message),p,n);
641 sha_info->offset=n;
642 /*
643 Reset working registers.
644 */
645 i=0;
646 n=0;
647 length=0;
648 return(WizardTrue);
649}
#define WizardAssert(domain, predicate)
#define ThrowWizardFatalError(domain, error)
@ HashDomain
Definition exception.h:30
@ CipherDomain
Definition exception.h:34
@ MemoryError
Definition exception.h:49
WizardBooleanType LogWizardEvent(const LogEventType type, const char *module, const char *function, const size_t line, const char *format,...)
Definition log.c:1390
@ TraceEvent
Definition log.h:39
#define GetWizardModule()
Definition log.h:30
WizardExport void * AcquireWizardMemory(const size_t size)
Definition memory.c:586
WizardExport void * CopyWizardMemory(void *destination, const void *source, const size_t size)
Definition memory.c:700
WizardExport void * AcquireQuantumMemory(const size_t count, const size_t quantum)
Definition memory.c:657
WizardExport void * RelinquishWizardMemory(void *memory)
Definition memory.c:1039
#define WizardExport
#define WizardSignature
WizardExport WizardBooleanType InitializeSHA1(SHA1Info *sha_info)
Definition sha1.c:382
WizardExport unsigned int GetSHA1Blocksize(const SHA1Info *sha1_info)
Definition sha1.c:292
WizardExport SHA1Info * DestroySHA1Info(SHA1Info *sha_info)
Definition sha1.c:160
#define SHA1Digestsize
Definition sha1.c:52
WizardExport WizardBooleanType UpdateSHA1(SHA1Info *sha_info, const StringInfo *message)
Definition sha1.c:592
#define SHA1Blocksize
Definition sha1.c:51
WizardExport WizardBooleanType FinalizeSHA1(SHA1Info *sha_info)
Definition sha1.c:199
WizardExport unsigned int GetSHA1Digestsize(const SHA1Info *sha1_info)
Definition sha1.c:352
static void TransformSHA1(SHA1Info *)
Definition sha1.c:431
WizardExport const StringInfo * GetSHA1Digest(const SHA1Info *sha1_info)
Definition sha1.c:322
static unsigned int RotateLeft(const unsigned int x, const unsigned int n)
Definition sha1.c:426
WizardExport SHA1Info * AcquireSHA1Info(void)
Definition sha1.c:109
#define Trunc32(x)
Definition signature.c:52
WizardExport size_t GetStringInfoLength(const StringInfo *string_info)
Definition string.c:1280
WizardExport StringInfo * AcquireStringInfo(const size_t length)
Definition string.c:179
WizardExport void SetStringInfoDatum(StringInfo *string_info, const unsigned char *source)
Definition string.c:1832
WizardExport unsigned char * GetStringInfoDatum(const StringInfo *string_info)
Definition string.c:1251
WizardExport StringInfo * DestroyStringInfo(StringInfo *string_info)
Definition string.c:857
unsigned int digestsize
Definition sha1.c:60
unsigned int low_order
Definition sha1.c:69
unsigned int high_order
Definition sha1.c:70
unsigned int blocksize
Definition sha1.c:61
time_t timestamp
Definition sha1.c:79
StringInfo * message
Definition sha1.c:65
WizardBooleanType lsb_first
Definition sha1.c:76
size_t signature
Definition sha1.c:82
size_t offset
Definition sha1.c:73
StringInfo * digest
Definition sha1.c:64
unsigned int * accumulator
Definition sha1.c:68
WizardBooleanType
Definition wizard-type.h:26
@ WizardTrue
Definition wizard-type.h:28
@ WizardFalse
Definition wizard-type.h:27