00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "wizard/studio.h"
00043 #include "wizard/exception.h"
00044 #include "wizard/exception-private.h"
00045 #include "wizard/memory_.h"
00046 #include "wizard/sha512.h"
00047
00048
00049
00050 #define SHA512Blocksize 128
00051 #define SHA512Digestsize 64
00052
00053
00054
00055
00056 struct _SHA512Info
00057 {
00058 unsigned int
00059 digestsize,
00060 blocksize;
00061
00062 StringInfo
00063 *digest,
00064 *message;
00065
00066 WizardSizeType
00067 *accumulator,
00068 low_order,
00069 high_order;
00070
00071 size_t
00072 offset;
00073
00074 WizardBooleanType
00075 lsb_first;
00076
00077 time_t
00078 timestamp;
00079
00080 size_t
00081 signature;
00082 };
00083
00084
00085
00086
00087 static void
00088 TransformSHA512(SHA512Info *);
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 WizardExport SHA512Info *AcquireSHA512Info(void)
00109 {
00110 SHA512Info
00111 *sha_info;
00112
00113 unsigned int
00114 lsb_first;
00115
00116 sha_info=(SHA512Info *) AcquireAlignedMemory(1,sizeof(*sha_info));
00117 if (sha_info == (SHA512Info *) NULL)
00118 ThrowWizardFatalError(HashError,MemoryError);
00119 (void) ResetWizardMemory(sha_info,0,sizeof(*sha_info));
00120 sha_info->digestsize=SHA512Digestsize;
00121 sha_info->blocksize=SHA512Blocksize;
00122 sha_info->digest=AcquireStringInfo(SHA512Digestsize);
00123 sha_info->message=AcquireStringInfo(SHA512Blocksize);
00124 sha_info->accumulator=(WizardSizeType *) AcquireQuantumMemory(SHA512Blocksize,
00125 sizeof(*sha_info->accumulator));
00126 if (sha_info->accumulator == (WizardSizeType *) NULL)
00127 ThrowWizardFatalError(HashError,MemoryError);
00128 lsb_first=1;
00129 sha_info->lsb_first=(int)
00130 (*(char *) &lsb_first) == 1 ? WizardTrue : WizardFalse;
00131 sha_info->timestamp=time((time_t *) NULL);
00132 sha_info->signature=WizardSignature;
00133 InitializeSHA512(sha_info);
00134 return(sha_info);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159 WizardExport SHA512Info *DestroySHA512Info(SHA512Info *sha_info)
00160 {
00161 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00162 assert(sha_info != (SHA512Info *) NULL);
00163 assert(sha_info->signature == WizardSignature);
00164 if (sha_info->accumulator != (WizardSizeType *) NULL)
00165 sha_info->accumulator=(WizardSizeType *)
00166 RelinquishWizardMemory(sha_info->accumulator);
00167 if (sha_info->message != (StringInfo *) NULL)
00168 sha_info->message=DestroyStringInfo(sha_info->message);
00169 if (sha_info->digest != (StringInfo *) NULL)
00170 sha_info->digest=DestroyStringInfo(sha_info->digest);
00171 sha_info->signature=(~WizardSignature);
00172 sha_info=(SHA512Info *) RelinquishWizardMemory(sha_info);
00173 return(sha_info);
00174 }
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199 WizardExport void FinalizeSHA512(SHA512Info *sha_info)
00200 {
00201 WizardOffsetType
00202 count;
00203
00204 register ssize_t
00205 i;
00206
00207 register unsigned char
00208 *q;
00209
00210 register WizardSizeType
00211 *p;
00212
00213 unsigned char
00214 *datum;
00215
00216 WizardSizeType
00217 high_order,
00218 low_order;
00219
00220
00221
00222
00223 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00224 assert(sha_info != (SHA512Info *) NULL);
00225 assert(sha_info->signature == WizardSignature);
00226 low_order=sha_info->low_order;
00227 high_order=sha_info->high_order;
00228 count=(WizardOffsetType) ((low_order >> 3) & 0x7f);
00229 datum=GetStringInfoDatum(sha_info->message);
00230 datum[count++]=(unsigned char) 0x80;
00231 if (count <= (WizardOffsetType) (GetStringInfoLength(sha_info->message)-16))
00232 (void) ResetWizardMemory(datum+count,0,(size_t) (GetStringInfoLength(
00233 sha_info->message)-16-count));
00234 else
00235 {
00236 (void) ResetWizardMemory(datum+count,0,(size_t) (GetStringInfoLength(
00237 sha_info->message)-count));
00238 TransformSHA512(sha_info);
00239 (void) ResetWizardMemory(datum,0,GetStringInfoLength(sha_info->message)-
00240 16);
00241 }
00242 datum[112]=(unsigned char) (high_order >> 56);
00243 datum[113]=(unsigned char) (high_order >> 48);
00244 datum[114]=(unsigned char) (high_order >> 40);
00245 datum[115]=(unsigned char) (high_order >> 32);
00246 datum[116]=(unsigned char) (high_order >> 24);
00247 datum[117]=(unsigned char) (high_order >> 16);
00248 datum[118]=(unsigned char) (high_order >> 8);
00249 datum[119]=(unsigned char) high_order;
00250 datum[120]=(unsigned char) (low_order >> 56);
00251 datum[121]=(unsigned char) (low_order >> 48);
00252 datum[122]=(unsigned char) (low_order >> 40);
00253 datum[123]=(unsigned char) (low_order >> 32);
00254 datum[124]=(unsigned char) (low_order >> 24);
00255 datum[125]=(unsigned char) (low_order >> 16);
00256 datum[126]=(unsigned char) (low_order >> 8);
00257 datum[127]=(unsigned char) low_order;
00258 TransformSHA512(sha_info);
00259 p=sha_info->accumulator;
00260 q=GetStringInfoDatum(sha_info->digest);
00261 for (i=0; i < (SHA512Digestsize/8); i++)
00262 {
00263 *q++=(unsigned char) ((*p >> 56) & 0xff);
00264 *q++=(unsigned char) ((*p >> 48) & 0xff);
00265 *q++=(unsigned char) ((*p >> 40) & 0xff);
00266 *q++=(unsigned char) ((*p >> 32) & 0xff);
00267 *q++=(unsigned char) ((*p >> 24) & 0xff);
00268 *q++=(unsigned char) ((*p >> 16) & 0xff);
00269 *q++=(unsigned char) ((*p >> 8) & 0xff);
00270 *q++=(unsigned char) (*p & 0xff);
00271 p++;
00272 }
00273
00274
00275
00276 count=0;
00277 high_order=0;
00278 low_order=0;
00279 }
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303 WizardExport unsigned int GetSHA512Blocksize(const SHA512Info *sha512_info)
00304 {
00305 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00306 WizardAssert(CipherDomain,sha512_info != (SHA512Info *) NULL);
00307 WizardAssert(CipherDomain,sha512_info->signature == WizardSignature);
00308 return(sha512_info->blocksize);
00309 }
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 WizardExport const StringInfo *GetSHA512Digest(const SHA512Info *sha512_info)
00334 {
00335 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00336 WizardAssert(HashDomain,sha512_info != (SHA512Info *) NULL);
00337 WizardAssert(HashDomain,sha512_info->signature == WizardSignature);
00338 return(sha512_info->digest);
00339 }
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363 WizardExport unsigned int GetSHA512Digestsize(const SHA512Info *sha512_info)
00364 {
00365 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00366 WizardAssert(CipherDomain,sha512_info != (SHA512Info *) NULL);
00367 WizardAssert(CipherDomain,sha512_info->signature == WizardSignature);
00368 return(sha512_info->digestsize);
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 WizardExport void InitializeSHA512(SHA512Info *sha_info)
00394 {
00395 (void) LogWizardEvent(TraceEvent,GetWizardModule(),"...");
00396 assert(sha_info != (SHA512Info *) NULL);
00397 assert(sha_info->signature == WizardSignature);
00398 sha_info->accumulator[0]=WizardULLConstant(0x6a09e667f3bcc908);
00399 sha_info->accumulator[1]=WizardULLConstant(0xbb67ae8584caa73b);
00400 sha_info->accumulator[2]=WizardULLConstant(0x3c6ef372fe94f82b);
00401 sha_info->accumulator[3]=WizardULLConstant(0xa54ff53a5f1d36f1);
00402 sha_info->accumulator[4]=WizardULLConstant(0x510e527fade682d1);
00403 sha_info->accumulator[5]=WizardULLConstant(0x9b05688c2b3e6c1f);
00404 sha_info->accumulator[6]=WizardULLConstant(0x1f83d9abfb41bd6b);
00405 sha_info->accumulator[7]=WizardULLConstant(0x5be0cd19137e2179);
00406 sha_info->low_order=0;
00407 sha_info->high_order=0;
00408 sha_info->offset=0;
00409 }
00410
00411
00412
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435 static inline WizardSizeType Ch(WizardSizeType x,WizardSizeType y,WizardSizeType z)
00436 {
00437 return((x & y) ^ (~x & z));
00438 }
00439
00440 static inline WizardSizeType Maj(WizardSizeType x, WizardSizeType y,WizardSizeType z)
00441 {
00442 return((x & y) ^ (x & z) ^ (y & z));
00443 }
00444
00445 static inline WizardSizeType Trunc64(WizardSizeType x)
00446 {
00447 return((WizardSizeType) (x & WizardULLConstant(0xffffffffffffffff)));
00448 }
00449
00450 static WizardSizeType RotateRight(WizardSizeType x,WizardSizeType n)
00451 {
00452 return(Trunc64((x >> n) | (x << (64-n))));
00453 }
00454
00455 static void TransformSHA512(SHA512Info *sha_info)
00456 {
00457 #define Sigma0(x) (RotateRight(x,1) ^ RotateRight(x,8) ^ Trunc64((x) >> 7))
00458 #define Sigma1(x) (RotateRight(x,19) ^ RotateRight(x,61) ^ Trunc64((x) >> 6))
00459 #define Suma0(x) (RotateRight(x,28) ^ RotateRight(x,34) ^ RotateRight(x,39))
00460 #define Suma1(x) (RotateRight(x,14) ^ RotateRight(x,18) ^ RotateRight(x,41))
00461
00462 ssize_t
00463 j;
00464
00465 register ssize_t
00466 i;
00467
00468 register unsigned char
00469 *p;
00470
00471 static WizardSizeType
00472 K[80] =
00473 {
00474 WizardULLConstant(0x428a2f98d728ae22),
00475 WizardULLConstant(0x7137449123ef65cd),
00476 WizardULLConstant(0xb5c0fbcfec4d3b2f),
00477 WizardULLConstant(0xe9b5dba58189dbbc),
00478 WizardULLConstant(0x3956c25bf348b538),
00479 WizardULLConstant(0x59f111f1b605d019),
00480 WizardULLConstant(0x923f82a4af194f9b),
00481 WizardULLConstant(0xab1c5ed5da6d8118),
00482 WizardULLConstant(0xd807aa98a3030242),
00483 WizardULLConstant(0x12835b0145706fbe),
00484 WizardULLConstant(0x243185be4ee4b28c),
00485 WizardULLConstant(0x550c7dc3d5ffb4e2),
00486 WizardULLConstant(0x72be5d74f27b896f),
00487 WizardULLConstant(0x80deb1fe3b1696b1),
00488 WizardULLConstant(0x9bdc06a725c71235),
00489 WizardULLConstant(0xc19bf174cf692694),
00490 WizardULLConstant(0xe49b69c19ef14ad2),
00491 WizardULLConstant(0xefbe4786384f25e3),
00492 WizardULLConstant(0x0fc19dc68b8cd5b5),
00493 WizardULLConstant(0x240ca1cc77ac9c65),
00494 WizardULLConstant(0x2de92c6f592b0275),
00495 WizardULLConstant(0x4a7484aa6ea6e483),
00496 WizardULLConstant(0x5cb0a9dcbd41fbd4),
00497 WizardULLConstant(0x76f988da831153b5),
00498 WizardULLConstant(0x983e5152ee66dfab),
00499 WizardULLConstant(0xa831c66d2db43210),
00500 WizardULLConstant(0xb00327c898fb213f),
00501 WizardULLConstant(0xbf597fc7beef0ee4),
00502 WizardULLConstant(0xc6e00bf33da88fc2),
00503 WizardULLConstant(0xd5a79147930aa725),
00504 WizardULLConstant(0x06ca6351e003826f),
00505 WizardULLConstant(0x142929670a0e6e70),
00506 WizardULLConstant(0x27b70a8546d22ffc),
00507 WizardULLConstant(0x2e1b21385c26c926),
00508 WizardULLConstant(0x4d2c6dfc5ac42aed),
00509 WizardULLConstant(0x53380d139d95b3df),
00510 WizardULLConstant(0x650a73548baf63de),
00511 WizardULLConstant(0x766a0abb3c77b2a8),
00512 WizardULLConstant(0x81c2c92e47edaee6),
00513 WizardULLConstant(0x92722c851482353b),
00514 WizardULLConstant(0xa2bfe8a14cf10364),
00515 WizardULLConstant(0xa81a664bbc423001),
00516 WizardULLConstant(0xc24b8b70d0f89791),
00517 WizardULLConstant(0xc76c51a30654be30),
00518 WizardULLConstant(0xd192e819d6ef5218),
00519 WizardULLConstant(0xd69906245565a910),
00520 WizardULLConstant(0xf40e35855771202a),
00521 WizardULLConstant(0x106aa07032bbd1b8),
00522 WizardULLConstant(0x19a4c116b8d2d0c8),
00523 WizardULLConstant(0x1e376c085141ab53),
00524 WizardULLConstant(0x2748774cdf8eeb99),
00525 WizardULLConstant(0x34b0bcb5e19b48a8),
00526 WizardULLConstant(0x391c0cb3c5c95a63),
00527 WizardULLConstant(0x4ed8aa4ae3418acb),
00528 WizardULLConstant(0x5b9cca4f7763e373),
00529 WizardULLConstant(0x682e6ff3d6b2b8a3),
00530 WizardULLConstant(0x748f82ee5defb2fc),
00531 WizardULLConstant(0x78a5636f43172f60),
00532 WizardULLConstant(0x84c87814a1f0ab72),
00533 WizardULLConstant(0x8cc702081a6439ec),
00534 WizardULLConstant(0x90befffa23631e28),
00535 WizardULLConstant(0xa4506cebde82bde9),
00536 WizardULLConstant(0xbef9a3f7b2c67915),
00537 WizardULLConstant(0xc67178f2e372532b),
00538 WizardULLConstant(0xca273eceea26619c),
00539 WizardULLConstant(0xd186b8c721c0c207),
00540 WizardULLConstant(0xeada7dd6cde0eb1e),
00541 WizardULLConstant(0xf57d4f7fee6ed178),
00542 WizardULLConstant(0x06f067aa72176fba),
00543 WizardULLConstant(0x0a637dc5a2c898a6),
00544 WizardULLConstant(0x113f9804bef90dae),
00545 WizardULLConstant(0x1b710b35131c471b),
00546 WizardULLConstant(0x28db77f523047d84),
00547 WizardULLConstant(0x32caab7b40c72493),
00548 WizardULLConstant(0x3c9ebe0a15c9bebc),
00549 WizardULLConstant(0x431d67c49c100d4c),
00550 WizardULLConstant(0x4cc5d4becb3e42b6),
00551 WizardULLConstant(0x597f299cfc657e2a),
00552 WizardULLConstant(0x5fcb6fab3ad6faec),
00553 WizardULLConstant(0x6c44198c4a475817)
00554 };
00555
00556 WizardSizeType
00557 A,
00558 B,
00559 C,
00560 D,
00561 E,
00562 F,
00563 G,
00564 H,
00565 T,
00566 T1,
00567 T2,
00568 W[80];
00569
00570 p=GetStringInfoDatum(sha_info->message);
00571 if (sha_info->lsb_first == WizardFalse)
00572 for (i=0; i < 16; i++)
00573 {
00574 T=(*((WizardSizeType *) p));
00575 p+=8;
00576 W[i]=(T);
00577 }
00578 else
00579 {
00580 for (i=0; i < 16; i++)
00581 {
00582 T=(*((WizardSizeType *) p));
00583 p+=8;
00584 W[i]=(WizardSizeType)
00585 (((T << 56) & WizardULLConstant(0xff00000000000000)) |
00586 ((T << 40) & WizardULLConstant(0x00ff000000000000)) |
00587 ((T << 24) & WizardULLConstant(0x0000ff0000000000)) |
00588 ((T << 8) & WizardULLConstant(0x000000ff00000000)) |
00589 ((T >> 8) & WizardULLConstant(0x00000000ff000000)) |
00590 ((T >> 24) & WizardULLConstant(0x0000000000ff0000)) |
00591 ((T >> 40) & WizardULLConstant(0x000000000000ff00)) |
00592 ((T >> 56) & WizardULLConstant(0x00000000000000ff)));
00593 }
00594 }
00595
00596
00597
00598 A=sha_info->accumulator[0];
00599 B=sha_info->accumulator[1];
00600 C=sha_info->accumulator[2];
00601 D=sha_info->accumulator[3];
00602 E=sha_info->accumulator[4];
00603 F=sha_info->accumulator[5];
00604 G=sha_info->accumulator[6];
00605 H=sha_info->accumulator[7];
00606 for (i=16; i < 80; i++)
00607 W[i]=Trunc64(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
00608 for (j=0; j < 80; j++)
00609 {
00610 T1=Trunc64(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
00611 T2=Trunc64(Suma0(A)+Maj(A,B,C));
00612 H=G;
00613 G=F;
00614 F=E;
00615 E=Trunc64(D+T1);
00616 D=C;
00617 C=B;
00618 B=A;
00619 A=Trunc64(T1+T2);
00620 }
00621
00622
00623
00624 sha_info->accumulator[0]=Trunc64(sha_info->accumulator[0]+A);
00625 sha_info->accumulator[1]=Trunc64(sha_info->accumulator[1]+B);
00626 sha_info->accumulator[2]=Trunc64(sha_info->accumulator[2]+C);
00627 sha_info->accumulator[3]=Trunc64(sha_info->accumulator[3]+D);
00628 sha_info->accumulator[4]=Trunc64(sha_info->accumulator[4]+E);
00629 sha_info->accumulator[5]=Trunc64(sha_info->accumulator[5]+F);
00630 sha_info->accumulator[6]=Trunc64(sha_info->accumulator[6]+G);
00631 sha_info->accumulator[7]=Trunc64(sha_info->accumulator[7]+H);
00632
00633
00634
00635 A=0;
00636 B=0;
00637 C=0;
00638 D=0;
00639 E=0;
00640 F=0;
00641 G=0;
00642 H=0;
00643 T=0;
00644 T1=0;
00645 T2=0;
00646 (void) ResetWizardMemory(W,0,sizeof(W));
00647 }
00648
00649
00650
00651
00652
00653
00654
00655
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667
00668
00669
00670
00671
00672
00673 WizardExport void UpdateSHA512(SHA512Info *sha_info,const StringInfo *message)
00674 {
00675 register size_t
00676 i;
00677
00678 register unsigned char
00679 *p;
00680
00681 WizardSizeType
00682 length,
00683 n;
00684
00685
00686
00687
00688 assert(sha_info != (SHA512Info *) NULL);
00689 assert(sha_info->signature == WizardSignature);
00690 n=(WizardSizeType) GetStringInfoLength(message);
00691 length=Trunc64(sha_info->low_order+(n << 3));
00692 if (length < sha_info->low_order)
00693 sha_info->high_order++;
00694 sha_info->low_order=length;
00695 sha_info->high_order+=(n >> 61);
00696 p=GetStringInfoDatum(message);
00697 if (sha_info->offset != 0)
00698 {
00699 i=GetStringInfoLength(sha_info->message)-sha_info->offset;
00700 if ((WizardSizeType) i > n)
00701 i=(size_t) n;
00702 (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message)+
00703 sha_info->offset,p,i);
00704 n-=i;
00705 p+=i;
00706 sha_info->offset+=i;
00707 if (sha_info->offset != GetStringInfoLength(sha_info->message))
00708 return;
00709 TransformSHA512(sha_info);
00710 }
00711 while (n >= (WizardSizeType) GetStringInfoLength(sha_info->message))
00712 {
00713 SetStringInfoDatum(sha_info->message,p);
00714 p+=GetStringInfoLength(sha_info->message);
00715 n-=GetStringInfoLength(sha_info->message);
00716 TransformSHA512(sha_info);
00717 }
00718 (void) CopyWizardMemory(GetStringInfoDatum(sha_info->message),p,(size_t) n);
00719 sha_info->offset=(size_t) n;
00720
00721
00722
00723 i=0;
00724 n=0;
00725 length=0;
00726 }