WizardsToolkit  1.0.7
signature.c
Go to the documentation of this file.
00001 /*
00002 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00003 %                                                                             %
00004 %                                                                             %
00005 %        SSSSS  IIIII   GGGG  N   N   AAA   TTTTT  U   U  RRRR   EEEEE        %
00006 %        SS       I    G      NN  N  A   A    T    U   U  R   R  E            %
00007 %         SSS     I    G  GG  N N N  AAAAA    T    U   U  RRRR   EEE          %
00008 %           SS    I    G   G  N  NN  A   A    T    U   U  R R    E            %
00009 %        SSSSS  IIIII   GGG   N   N  A   A    T     UUU   R  R   EEEEE        %
00010 %                                                                             %
00011 %                                                                             %
00012 %             Methods to Compute a Message Digest for an Image                %
00013 %                                                                             %
00014 %                             Software Design                                 %
00015 %                               John Cristy                                   %
00016 %                              December 1992                                  %
00017 %                                                                             %
00018 %                                                                             %
00019 %  Copyright 1999-2011 ImageMagick Studio LLC, a non-profit organization      %
00020 %  dedicated to making software imaging solutions freely available.           %
00021 %                                                                             %
00022 %  You may not use this file except in compliance with the License.  You may  %
00023 %  obtain a copy of the License at                                            %
00024 %                                                                             %
00025 %    http://www.wizards-toolkit.org/script/license.php                        %
00026 %                                                                             %
00027 %  Unless required by applicable law or agreed to in writing, software        %
00028 %  distributed under the License is distributed on an "AS IS" BASIS,          %
00029 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
00030 %  See the License for the specific language governing permissions and        %
00031 %  limitations under the License.                                             %
00032 %                                                                             %
00033 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00034 %
00035 %
00036 %
00037 */
00038 
00039 /*
00040   Include declarations.
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/signature.h"
00047 #include "wizard/string_.h"
00048 
00049 /*
00050   Define declarations.
00051 */
00052 #define Trunc32(x)  ((x) & 0xffffffffUL)
00053 
00054 /*
00055   Forward declarations.
00056 */
00057 static void
00058   TransformSignature(SignatureInfo *);
00059 
00060 /*
00061 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00062 %                                                                             %
00063 %                                                                             %
00064 %                                                                             %
00065 +   F i n a l i z e S i g n a t u r e                                         %
00066 %                                                                             %
00067 %                                                                             %
00068 %                                                                             %
00069 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00070 %
00071 %  FinalizeSignature() finalizes the SHA message digest computation.
00072 %
00073 %  The format of the FinalizeSignature method is:
00074 %
00075 %      FinalizeSignature(SignatureInfo *signature_info)
00076 %
00077 %  A description of each parameter follows:
00078 %
00079 %    o signature_info: The address of a structure of type SignatureInfo.
00080 %
00081 %
00082 */
00083 WizardExport void FinalizeSignature(SignatureInfo *signature_info)
00084 {
00085   ssize_t
00086     count;
00087 
00088   size_t
00089     high_order,
00090     low_order;
00091 
00092   /*
00093     Add padding and return the message digest.
00094   */
00095   assert(signature_info != (SignatureInfo *) NULL);
00096   assert(signature_info->signature == WizardSignature);
00097   low_order=signature_info->low_order;
00098   high_order=signature_info->high_order;
00099   count=(ssize_t) ((low_order >> 3) & 0x3f);
00100   signature_info->message[count++]=(unsigned char) 0x80;
00101   if (count <= (WizardSignatureSize-8))
00102     (void) ResetWizardMemory(signature_info->message+count,0,(size_t)
00103       (WizardSignatureSize-8-count));
00104   else
00105     {
00106       (void) ResetWizardMemory(signature_info->message+count,0,(size_t)
00107         (WizardSignatureSize-count));
00108       TransformSignature(signature_info);
00109       (void) ResetWizardMemory(signature_info->message,0,WizardSignatureSize-8);
00110     }
00111   signature_info->message[56]=(unsigned char) (high_order >> 24);
00112   signature_info->message[57]=(unsigned char) (high_order >> 16);
00113   signature_info->message[58]=(unsigned char) (high_order >> 8);
00114   signature_info->message[59]=(unsigned char) high_order;
00115   signature_info->message[60]=(unsigned char) (low_order >> 24);
00116   signature_info->message[61]=(unsigned char) (low_order >> 16);
00117   signature_info->message[62]=(unsigned char) (low_order >> 8);
00118   signature_info->message[63]=(unsigned char) low_order;
00119   TransformSignature(signature_info);
00120 }
00121 
00122 /*
00123 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00124 %                                                                             %
00125 %                                                                             %
00126 %                                                                             %
00127 +   G e t S i g n a t u r e I n f o                                           %
00128 %                                                                             %
00129 %                                                                             %
00130 %                                                                             %
00131 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00132 %
00133 %  GetSignatureInfo() initializes the SHA message digest structure.
00134 %
00135 %  The format of the GetSignatureInfo method is:
00136 %
00137 %      GetSignatureInfo(SignatureInfo *signature_info)
00138 %
00139 %  A description of each parameter follows:
00140 %
00141 %    o signature_info: The address of a structure of type SignatureInfo.
00142 %
00143 %
00144 */
00145 WizardExport void GetSignatureInfo(SignatureInfo *signature_info)
00146 {
00147   size_t
00148     lsb_first;
00149 
00150   assert(signature_info != (SignatureInfo *) NULL);
00151   (void) ResetWizardMemory(signature_info,0,sizeof(*signature_info));
00152   signature_info->digest[0]=0x6a09e667UL;
00153   signature_info->digest[1]=0xbb67ae85UL;
00154   signature_info->digest[2]=0x3c6ef372UL;
00155   signature_info->digest[3]=0xa54ff53aUL;
00156   signature_info->digest[4]=0x510e527fUL;
00157   signature_info->digest[5]=0x9b05688cUL;
00158   signature_info->digest[6]=0x1f83d9abUL;
00159   signature_info->digest[7]=0x5be0cd19UL;
00160   lsb_first=1;
00161   signature_info->lsb_first=(int)
00162     (*(char *) &lsb_first) == 1 ? WizardTrue : WizardFalse;
00163   signature_info->signature=WizardSignature;
00164 }
00165 
00166 /*
00167 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00168 %                                                                             %
00169 %                                                                             %
00170 %                                                                             %
00171 +   T r a n s f o r m S i g n a t u r e                                       %
00172 %                                                                             %
00173 %                                                                             %
00174 %                                                                             %
00175 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00176 %
00177 %  TransformSignature() transforms the SHA message digest.
00178 %
00179 %  The format of the TransformSignature method is:
00180 %
00181 %      TransformSignature(SignatureInfo *signature_info)
00182 %
00183 %  A description of each parameter follows:
00184 %
00185 %    o signature_info: The address of a structure of type SignatureInfo.
00186 %
00187 %
00188 */
00189 static void TransformSignature(SignatureInfo *signature_info)
00190 {
00191 #define Ch(x,y,z)  (((x) & (y)) ^ (~(x) & (z)))
00192 #define Maj(x,y,z)  (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
00193 #define RotateRight(x,n)  Trunc32((((x) >> (n)) | ((x) << (32-(n)))))
00194 #define Sigma0(x)  (RotateRight(x,7) ^ RotateRight(x,18) ^ Trunc32((x) >> 3))
00195 #define Sigma1(x)  (RotateRight(x,17) ^ RotateRight(x,19) ^ Trunc32((x) >> 10))
00196 #define Suma0(x)  (RotateRight(x,2) ^ RotateRight(x,13) ^ RotateRight(x,22))
00197 #define Suma1(x)  (RotateRight(x,6) ^ RotateRight(x,11) ^ RotateRight(x,25))
00198 
00199   ssize_t
00200     j;
00201 
00202   register ssize_t
00203     i;
00204 
00205   register unsigned char
00206     *p;
00207 
00208   static size_t
00209     K[64] =
00210     {
00211       0x428a2f98UL, 0x71374491UL, 0xb5c0fbcfUL, 0xe9b5dba5UL, 0x3956c25bUL,
00212       0x59f111f1UL, 0x923f82a4UL, 0xab1c5ed5UL, 0xd807aa98UL, 0x12835b01UL,
00213       0x243185beUL, 0x550c7dc3UL, 0x72be5d74UL, 0x80deb1feUL, 0x9bdc06a7UL,
00214       0xc19bf174UL, 0xe49b69c1UL, 0xefbe4786UL, 0x0fc19dc6UL, 0x240ca1ccUL,
00215       0x2de92c6fUL, 0x4a7484aaUL, 0x5cb0a9dcUL, 0x76f988daUL, 0x983e5152UL,
00216       0xa831c66dUL, 0xb00327c8UL, 0xbf597fc7UL, 0xc6e00bf3UL, 0xd5a79147UL,
00217       0x06ca6351UL, 0x14292967UL, 0x27b70a85UL, 0x2e1b2138UL, 0x4d2c6dfcUL,
00218       0x53380d13UL, 0x650a7354UL, 0x766a0abbUL, 0x81c2c92eUL, 0x92722c85UL,
00219       0xa2bfe8a1UL, 0xa81a664bUL, 0xc24b8b70UL, 0xc76c51a3UL, 0xd192e819UL,
00220       0xd6990624UL, 0xf40e3585UL, 0x106aa070UL, 0x19a4c116UL, 0x1e376c08UL,
00221       0x2748774cUL, 0x34b0bcb5UL, 0x391c0cb3UL, 0x4ed8aa4aUL, 0x5b9cca4fUL,
00222       0x682e6ff3UL, 0x748f82eeUL, 0x78a5636fUL, 0x84c87814UL, 0x8cc70208UL,
00223       0x90befffaUL, 0xa4506cebUL, 0xbef9a3f7UL, 0xc67178f2UL
00224     };  /* 32-bit fractional part of the cube root of the first 64 primes */
00225 
00226   size_t
00227     A,
00228     B,
00229     C,
00230     D,
00231     E,
00232     F,
00233     G,
00234     H,
00235     shift,
00236     T,
00237     T1,
00238     T2,
00239     W[64];
00240 
00241   shift=32;
00242   p=signature_info->message;
00243   if (signature_info->lsb_first == WizardFalse)
00244     {
00245       if (sizeof(size_t) <= 4)
00246         for (i=0; i < 16; i++)
00247         {
00248           T=(*((size_t *) p));
00249           p+=4;
00250           W[i]=Trunc32(T);
00251         }
00252       else
00253         for (i=0; i < 16; i+=2)
00254         {
00255           T=(*((size_t *) p));
00256           p+=8;
00257           W[i]=Trunc32(T >> shift);
00258           W[i+1]=Trunc32(T);
00259         }
00260     }
00261   else
00262     if (sizeof(size_t) <= 4)
00263       for (i=0; i < 16; i++)
00264       {
00265         T=(*((size_t *) p));
00266         p+=4;
00267         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00268           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00269       }
00270     else
00271       for (i=0; i < 16; i+=2)
00272       {
00273         T=(*((size_t *) p));
00274         p+=8;
00275         W[i]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00276           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00277         T>>=shift;
00278         W[i+1]=((T << 24) & 0xff000000) | ((T << 8) & 0x00ff0000) |
00279           ((T >> 8) & 0x0000ff00) | ((T >> 24) & 0x000000ff);
00280       }
00281   /*
00282     Copy digest to registers.
00283   */
00284   A=signature_info->digest[0];
00285   B=signature_info->digest[1];
00286   C=signature_info->digest[2];
00287   D=signature_info->digest[3];
00288   E=signature_info->digest[4];
00289   F=signature_info->digest[5];
00290   G=signature_info->digest[6];
00291   H=signature_info->digest[7];
00292   for (i=16; i < 64; i++)
00293     W[i]=Trunc32(Sigma1(W[i-2])+W[i-7]+Sigma0(W[i-15])+W[i-16]);
00294   for (j=0; j < 64; j++)
00295   {
00296     T1=Trunc32(H+Suma1(E)+Ch(E,F,G)+K[j]+W[j]);
00297     T2=Trunc32(Suma0(A)+Maj(A,B,C));
00298     H=G;
00299     G=F;
00300     F=E;
00301     E=Trunc32(D+T1);
00302     D=C;
00303     C=B;
00304     B=A;
00305     A=Trunc32(T1+T2);
00306   }
00307   /*
00308     Add registers back to digest.
00309   */
00310   signature_info->digest[0]=Trunc32(signature_info->digest[0]+A);
00311   signature_info->digest[1]=Trunc32(signature_info->digest[1]+B);
00312   signature_info->digest[2]=Trunc32(signature_info->digest[2]+C);
00313   signature_info->digest[3]=Trunc32(signature_info->digest[3]+D);
00314   signature_info->digest[4]=Trunc32(signature_info->digest[4]+E);
00315   signature_info->digest[5]=Trunc32(signature_info->digest[5]+F);
00316   signature_info->digest[6]=Trunc32(signature_info->digest[6]+G);
00317   signature_info->digest[7]=Trunc32(signature_info->digest[7]+H);
00318 }
00319 
00320 /*
00321 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00322 %                                                                             %
00323 %                                                                             %
00324 %                                                                             %
00325 +   U p d a t e S i g n a t u r e                                             %
00326 %                                                                             %
00327 %                                                                             %
00328 %                                                                             %
00329 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
00330 %
00331 %  UpdateSignature() updates the SHA message digest.
00332 %
00333 %  The format of the UpdateSignature method is:
00334 %
00335 %      UpdateSignature(SignatureInfo *signature_info,
00336 %        const unsigned char *message,const size_t length)
00337 %
00338 %  A description of each parameter follows:
00339 %
00340 %    o signature_info: The address of a structure of type SignatureInfo.
00341 %
00342 %    o message: the message
00343 %
00344 %    o length: The length of the message.
00345 %
00346 %
00347 */
00348 WizardExport void UpdateSignature(SignatureInfo *signature_info,
00349   const unsigned char *message,const size_t length)
00350 {
00351   register ssize_t
00352     i;
00353 
00354   size_t
00355     count,
00356     n;
00357 
00358   /*
00359     Update the SHA digest.
00360   */
00361   assert(signature_info != (SignatureInfo *) NULL);
00362   assert(signature_info->signature == WizardSignature);
00363   n=(size_t) length;
00364   count=Trunc32(signature_info->low_order+(n << 3));
00365   if (count < signature_info->low_order)
00366     signature_info->high_order++;
00367   signature_info->low_order=count;
00368   signature_info->high_order+=(n >> 29);
00369   if (signature_info->offset != 0)
00370     {
00371       i=WizardSignatureSize-signature_info->offset;
00372       if (i > (ssize_t) n)
00373         i=(ssize_t) n;
00374       (void) CopyWizardMemory(signature_info->message+signature_info->offset,
00375         message,(size_t) i);
00376       n-=i;
00377       message+=i;
00378       signature_info->offset+=i;
00379       if (signature_info->offset != WizardSignatureSize)
00380         return;
00381       TransformSignature(signature_info);
00382     }
00383   while (n >= WizardSignatureSize)
00384   {
00385     (void) CopyWizardMemory(signature_info->message,message,
00386       WizardSignatureSize);
00387     message+=WizardSignatureSize;
00388     n-=WizardSignatureSize;
00389     TransformSignature(signature_info);
00390   }
00391   (void) CopyWizardMemory(signature_info->message,message,(size_t) n);
00392   signature_info->offset=(ssize_t) n;
00393 }