TAY

Fork of Crypto_light by Edward Stott

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHA2_32.cpp Source File

SHA2_32.cpp

00001 #include "SHA2_32.h"
00002 #include "string.h"
00003 
00004 
00005 static const uint8_t MASK = 0x0F;
00006 
00007 #define W(t) (w[(t)] = SSIG1(w[((t)+14)&MASK]) + w[((t)+9)&MASK] + SSIG0(w[((t)+1)&MASK]) + w[t])
00008 
00009 #define ROTL(W,N) (((W) << (N)) | ((W) >> (32-(N))))
00010 #define ROTR(W,N) (rotRWord(W,N)) 
00011 #define CH(X,Y,Z) (((X) & (Y)) ^ ((~(X)) & (Z)))
00012 #define MAJ(X,Y,Z) (((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z)))
00013 #define BSIG0(X) (ROTR(X,2) ^ ROTR(X,13) ^ ROTR(X,22))
00014 #define BSIG1(X) (ROTR(X,6) ^ ROTR(X,11) ^ ROTR(X,25))
00015 #define SSIG0(X) (ROTR((X),7) ^ ROTR((X),18) ^ ((X) >> 3))
00016 #define SSIG1(X) (ROTR((X),17) ^ ROTR((X),19) ^ ((X) >> 10))
00017 #define R(A,B,C,D,E,F,G,H,T,K)  T1 = H + BSIG1(E) + CH(E,F,G) + K + (w[T] = revWord(buffer2[T])); \
00018                               T2 = BSIG0(A) + MAJ(A,B,C); \
00019                               D += T1; \
00020                               H = T1 + T2;
00021 #define R2(A,B,C,D,E,F,G,H,T,K)  T1 = H + BSIG1(E) + CH(E,F,G) + K + W(T&MASK); \
00022                               T2 = BSIG0(A) + MAJ(A,B,C); \
00023                               D += T1; \
00024                               H = T1 + T2;
00025         
00026 static const uint32_t H[] =
00027 {
00028     // SHA-224
00029     0xc1059ed8, 0x367cd507, 0x3070dd17, 0xf70e5939,
00030     0xffc00b31, 0x68581511, 0x64f98fa7, 0xbefa4fa4,
00031     
00032     // SHA-256      
00033     0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a,
00034     0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
00035 };
00036 
00037 inline static uint32_t revWord(const uint32_t w)
00038 {
00039 #ifdef __CC_ARM
00040     return __rev(w);
00041 #else
00042     return (w >> 24)
00043          | ((w & 0x00FF0000) >> 8)
00044          | ((w & 0x0000FF00) << 8)
00045          | ((w & 0x000000FF) << 24);
00046 #endif
00047 } 
00048 
00049 inline static uint32_t rotRWord(const uint32_t w, const uint32_t n)
00050 {
00051 #ifdef __CC_ARM
00052     return __ror(w, n);
00053 #else
00054     return (w >> n) | (w << (32-n));
00055 #endif
00056 }
00057 
00058 SHA2_32::SHA2_32(SHA_32_TYPE t):
00059 type(t),
00060 totalBufferLength(0),
00061 bufferLength(0)
00062 {
00063     switch(type)
00064     {
00065         case SHA_224:
00066             h0 = H[0];
00067             h1 = H[1];
00068             h2 = H[2];
00069             h3 = H[3];
00070             h4 = H[4];
00071             h5 = H[5];
00072             h6 = H[6];
00073             h7 = H[7];
00074         break;
00075         
00076         case SHA_256:
00077             h0 = H[8];
00078             h1 = H[9];
00079             h2 = H[10];
00080             h3 = H[11];
00081             h4 = H[12];
00082             h5 = H[13];
00083             h6 = H[14];
00084             h7 = H[15];     
00085         break;
00086     }
00087 }
00088 
00089 void SHA2_32::update(uint8_t *data, uint32_t length)
00090 {
00091     if((int)length < 64-bufferLength)
00092     {
00093         memcpy(&buffer[bufferLength], data, length);
00094         bufferLength += length;
00095         totalBufferLength += length;
00096         return;
00097     }
00098     int offset = 64-bufferLength;
00099     memcpy(&buffer[bufferLength], data, offset);
00100     computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
00101     while(length-offset > 64)
00102     {
00103         memcpy(buffer, &data[offset], 64);
00104         computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
00105         offset += 64;
00106     }
00107     if(offset > (int)length)
00108         offset -= 64;
00109     bufferLength = length - offset;
00110     memcpy(buffer, &data[offset], bufferLength);
00111     totalBufferLength += length;
00112 }
00113 
00114 void SHA2_32::finalize(uint8_t *hash)
00115 {
00116     uint32_t *hash2 = (uint32_t*)hash;
00117     uint16_t padding;
00118     if(totalBufferLength % 64 < 56)
00119         padding = 56 - (totalBufferLength % 64);
00120     else
00121         padding = 56 + (64 - (totalBufferLength % 64));
00122 
00123     buffer[bufferLength++] = 0x80;
00124     padding--;
00125     if(padding+bufferLength == 56)
00126         memset(&buffer[bufferLength], 0, padding);
00127     else
00128     {
00129         memset(&buffer[bufferLength], 0, 64-bufferLength);
00130         computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
00131         memset(buffer, 0, 56);
00132     }
00133     
00134     uint64_t lengthBit = totalBufferLength << 3;
00135     uint32_t lengthBitLow = lengthBit;
00136     uint32_t lengthBitHigh = lengthBit >> 32;
00137     lengthBitLow = revWord(lengthBitLow);
00138     lengthBitHigh = revWord(lengthBitHigh);
00139     memcpy(&buffer[60], &lengthBitLow, 4);    
00140     memcpy(&buffer[56], &lengthBitHigh, 4);    
00141     computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
00142 
00143     hash2[0] = revWord(h0);
00144     hash2[1] = revWord(h1);
00145     hash2[2] = revWord(h2);
00146     hash2[3] = revWord(h3);
00147     hash2[4] = revWord(h4);
00148     hash2[5] = revWord(h5);
00149     hash2[6] = revWord(h6);
00150 
00151     
00152     if(type == SHA_256)
00153         hash2[7] = revWord(h7);
00154     
00155     // reset state
00156     switch(type)
00157     {
00158         case SHA_224:
00159             h0 = H[0];
00160             h1 = H[1];
00161             h2 = H[2];
00162             h3 = H[3];
00163             h4 = H[4];
00164             h5 = H[5];
00165             h6 = H[6];
00166             h7 = H[7];
00167         break;
00168         
00169         case SHA_256:
00170             h0 = H[8];
00171             h1 = H[9];
00172             h2 = H[10];
00173             h3 = H[11];
00174             h4 = H[12];
00175             h5 = H[13];
00176             h6 = H[14];
00177             h7 = H[15];     
00178         break;
00179     }
00180     totalBufferLength = 0;
00181     bufferLength = 0;
00182 }
00183 
00184 void SHA2_32::computeHash(SHA_32_TYPE type, uint8_t *hash, uint8_t *data, uint32_t length)
00185 {
00186     uint32_t *hash2 = (uint32_t*)hash;
00187     
00188     uint32_t h[8];
00189     h[0] = H[type*8];
00190     h[1] = H[type*8+1];
00191     h[2] = H[type*8+2];
00192     h[3] = H[type*8+3];
00193     h[4] = H[type*8+4];
00194     h[5] = H[type*8+5];
00195     h[6] = H[type*8+6];
00196     h[7] = H[type*8+7];
00197     
00198     uint64_t lengthBit = length << 3;
00199     uint32_t padding;
00200     if(length % 64 < 56)
00201         padding = 56 - (length % 64);
00202     else
00203         padding = 56 + (64 - (length % 64));
00204         
00205     while(length >= 64)
00206     {
00207         computeBlock(h, &h[1], &h[2], &h[3], &h[4], &h[5], &h[6], &h[7], data);
00208         length -= 64;
00209         data += 64;
00210     }
00211     uint8_t buffer[64];
00212     memcpy(buffer, data,length); 
00213     buffer[length++] = 0x80;
00214     padding--;
00215     if(padding+length == 56)
00216         memset(&buffer[length], 0, padding);
00217     else
00218     {
00219         memset(&buffer[length], 0, 64-length);
00220         computeBlock(h, &h[1], &h[2], &h[3], &h[4], &h[5], &h[6], &h[7], buffer);
00221         memset(buffer, 0, 56);
00222     }
00223     
00224     uint32_t lengthBitLow = lengthBit;
00225     uint32_t lengthBitHigh = lengthBit >> 32;
00226     lengthBitLow = revWord(lengthBitLow);
00227     memcpy(&buffer[60], &lengthBitLow, 4);
00228     lengthBitHigh = revWord(lengthBitHigh);
00229     memcpy(&buffer[56], &lengthBitHigh, 4);    
00230     computeBlock(h, &h[1], &h[2], &h[3], &h[4], &h[5], &h[6], &h[7], buffer);
00231 
00232     hash2[0] = revWord(h[0]);
00233     hash2[1] = revWord(h[1]);
00234     hash2[2] = revWord(h[2]);
00235     hash2[3] = revWord(h[3]);
00236     hash2[4] = revWord(h[4]);
00237     hash2[5] = revWord(h[5]);
00238     hash2[6] = revWord(h[6]);
00239 
00240     
00241     if(type == SHA_256)
00242         hash2[7] = revWord(h[7]);
00243 }
00244 
00245 
00246 #ifdef __CC_ARM
00247 //__forceinline 
00248 #endif 
00249 void SHA2_32::computeBlock(uint32_t *h02, 
00250                         uint32_t *h12, 
00251                         uint32_t *h22, 
00252                         uint32_t *h32, 
00253                         uint32_t *h42, 
00254                         uint32_t *h52, 
00255                         uint32_t *h62,
00256                         uint32_t *h72,
00257                         uint8_t *buffer)
00258 {
00259     uint32_t w[16];
00260     uint32_t *buffer2 = (uint32_t*)buffer;
00261     uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42, f = *h52, g = *h62, h = *h72;
00262     uint32_t T1, T2;
00263 
00264     R(a,b,c,d,e,f,g,h,0,0x428a2f98)
00265     R(h,a,b,c,d,e,f,g,1,0x71374491)
00266     R(g,h,a,b,c,d,e,f,2,0xb5c0fbcf)
00267     R(f,g,h,a,b,c,d,e,3,0xe9b5dba5)
00268     R(e,f,g,h,a,b,c,d,4,0x3956c25b)
00269     R(d,e,f,g,h,a,b,c,5,0x59f111f1)
00270     R(c,d,e,f,g,h,a,b,6,0x923f82a4)
00271     R(b,c,d,e,f,g,h,a,7,0xab1c5ed5)
00272 
00273     R(a,b,c,d,e,f,g,h,8,0xd807aa98)
00274     R(h,a,b,c,d,e,f,g,9,0x12835b01)
00275     R(g,h,a,b,c,d,e,f,10,0x243185be)
00276     R(f,g,h,a,b,c,d,e,11,0x550c7dc3)
00277     R(e,f,g,h,a,b,c,d,12,0x72be5d74)
00278     R(d,e,f,g,h,a,b,c,13,0x80deb1fe)
00279     R(c,d,e,f,g,h,a,b,14,0x9bdc06a7)
00280     R(b,c,d,e,f,g,h,a,15,0xc19bf174)
00281 
00282     R2(a,b,c,d,e,f,g,h,16,0xe49b69c1)
00283     R2(h,a,b,c,d,e,f,g,17,0xefbe4786)
00284     R2(g,h,a,b,c,d,e,f,18,0x0fc19dc6)
00285     R2(f,g,h,a,b,c,d,e,19,0x240ca1cc)
00286     R2(e,f,g,h,a,b,c,d,20,0x2de92c6f)
00287     R2(d,e,f,g,h,a,b,c,21,0x4a7484aa)
00288     R2(c,d,e,f,g,h,a,b,22,0x5cb0a9dc)
00289     R2(b,c,d,e,f,g,h,a,23,0x76f988da)
00290     
00291     R2(a,b,c,d,e,f,g,h,24,0x983e5152)
00292     R2(h,a,b,c,d,e,f,g,25,0xa831c66d)
00293     R2(g,h,a,b,c,d,e,f,26,0xb00327c8)
00294     R2(f,g,h,a,b,c,d,e,27,0xbf597fc7)
00295     R2(e,f,g,h,a,b,c,d,28,0xc6e00bf3)
00296     R2(d,e,f,g,h,a,b,c,29,0xd5a79147)
00297     R2(c,d,e,f,g,h,a,b,30,0x06ca6351)
00298     R2(b,c,d,e,f,g,h,a,31,0x14292967) 
00299 
00300     R2(a,b,c,d,e,f,g,h,32,0x27b70a85)
00301     R2(h,a,b,c,d,e,f,g,33,0x2e1b2138)
00302     R2(g,h,a,b,c,d,e,f,34,0x4d2c6dfc)
00303     R2(f,g,h,a,b,c,d,e,35,0x53380d13)
00304     R2(e,f,g,h,a,b,c,d,36,0x650a7354)
00305     R2(d,e,f,g,h,a,b,c,37,0x766a0abb)
00306     R2(c,d,e,f,g,h,a,b,38,0x81c2c92e)
00307     R2(b,c,d,e,f,g,h,a,39,0x92722c85)
00308     
00309     R2(a,b,c,d,e,f,g,h,40,0xa2bfe8a1)
00310     R2(h,a,b,c,d,e,f,g,41,0xa81a664b)
00311     R2(g,h,a,b,c,d,e,f,42,0xc24b8b70)
00312     R2(f,g,h,a,b,c,d,e,43,0xc76c51a3)
00313     R2(e,f,g,h,a,b,c,d,44,0xd192e819)
00314     R2(d,e,f,g,h,a,b,c,45,0xd6990624)
00315     R2(c,d,e,f,g,h,a,b,46,0xf40e3585)
00316     R2(b,c,d,e,f,g,h,a,47,0x106aa070)
00317     
00318     R2(a,b,c,d,e,f,g,h,48,0x19a4c116)
00319     R2(h,a,b,c,d,e,f,g,49,0x1e376c08)
00320     R2(g,h,a,b,c,d,e,f,50,0x2748774c)
00321     R2(f,g,h,a,b,c,d,e,51,0x34b0bcb5)
00322     R2(e,f,g,h,a,b,c,d,52,0x391c0cb3)
00323     R2(d,e,f,g,h,a,b,c,53,0x4ed8aa4a)
00324     R2(c,d,e,f,g,h,a,b,54,0x5b9cca4f)
00325     R2(b,c,d,e,f,g,h,a,55,0x682e6ff3)
00326     
00327     R2(a,b,c,d,e,f,g,h,56,0x748f82ee)
00328     R2(h,a,b,c,d,e,f,g,57,0x78a5636f)
00329     R2(g,h,a,b,c,d,e,f,58,0x84c87814)
00330     R2(f,g,h,a,b,c,d,e,59,0x8cc70208)
00331     R2(e,f,g,h,a,b,c,d,60,0x90befffa)
00332     R2(d,e,f,g,h,a,b,c,61,0xa4506ceb)
00333     R2(c,d,e,f,g,h,a,b,62,0xbef9a3f7)
00334     R2(b,c,d,e,f,g,h,a,63,0xc67178f2)
00335     
00336     
00337     *h02 += a;
00338     *h12 += b;
00339     *h22 += c;
00340     *h32 += d;
00341     *h42 += e;
00342     *h52 += f;
00343     *h62 += g;
00344     *h72 += h;
00345 }