This library implements some hash and cryptographic algorithms.

Dependents:   mBuinoBlinky PB_Emma_Ethernet SLOTrashHTTP Garagem ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SHA2_64.cpp Source File

SHA2_64.cpp

00001 #include "SHA2_64.h"
00002 #include <string.h>
00003 
00004 
00005 static const uint64_t H[] =
00006 {
00007     // SHA-384
00008     0xcbbb9d5dc1059ed8, 0x629a292a367cd507, 0x9159015a3070dd17, 0x152fecd8f70e5939,
00009     0x67332667ffc00b31, 0x8eb44a8768581511, 0xdb0c2e0d64f98fa7, 0x47b5481dbefa4fa4,
00010 
00011     // SHA-512
00012     0x6a09e667f3bcc908, 0xbb67ae8584caa73b, 0x3c6ef372fe94f82b, 0xa54ff53a5f1d36f1,
00013     0x510e527fade682d1, 0x9b05688c2b3e6c1f, 0x1f83d9abfb41bd6b, 0x5be0cd19137e2179
00014 };
00015 
00016 static uint64_t revWord(uint64_t w)
00017 {
00018 #ifdef __CC_ARM
00019     return __rev(w >> 32) 
00020          | ((uint64_t)(__rev(w)) << 32);
00021 #else
00022     return (w >> 56)
00023          | ((w & 0x00FF000000000000) >> 40)
00024          | ((w & 0x0000FF0000000000) >> 24)
00025          | ((w & 0x000000FF00000000) >> 8)
00026          | ((w & 0x00000000FF000000) << 8)
00027          | ((w & 0x0000000000FF0000) << 24)
00028          | ((w & 0x000000000000FF00) << 40)
00029          | ((w & 0x00000000000000FF) << 56);
00030 #endif
00031 }
00032 
00033 #define ROTL(W,N) (((W) << (N)) | ((W) >> (64-(N))))
00034 #define ROTR(W,N) (((W) >> (N)) | ((W) << (64-(N))))
00035 #define CH(X,Y,Z) (((X) & (Y)) ^ ((~(X)) & (Z)))
00036 #define MAJ(X,Y,Z) (((X) & (Y)) ^ ((X) & (Z)) ^ ((Y) & (Z)))
00037 #define BSIG0(X) (ROTR(X,28) ^ ROTR(X,34) ^ ROTR(X,39))
00038 #define BSIG1(X) (ROTR(X,14) ^ ROTR(X,18) ^ ROTR(X,41))
00039 #define SSIG0(X) (ROTR((X),1) ^ ROTR((X),8) ^ ((X) >> 7))
00040 #define SSIG1(X) (ROTR((X),19) ^ ROTR((X),61) ^ ((X) >> 6))
00041 
00042 #define R(A,B,C,D,E,F,G,H,K,T)  T1 = H + BSIG1(E) + CH(E,F,G) + K + w[T]; \
00043                               T2 = BSIG0(A) + MAJ(A,B,C); \
00044                               D += T1; \
00045                               H = T1 + T2;    
00046                           
00047 
00048 SHA2_64::SHA2_64(SHA2_64_TYPE t):
00049 type(t),
00050 totalBufferLength(0),
00051 bufferLength(0)
00052 {
00053     switch(type)
00054     {
00055         case SHA_384:
00056             h0 = H[0];
00057             h1 = H[1];
00058             h2 = H[2];
00059             h3 = H[3];
00060             h4 = H[4];
00061             h5 = H[5];
00062             h6 = H[6];
00063             h7 = H[7];
00064         break;
00065         
00066         case SHA_512:
00067             h0 = H[8];
00068             h1 = H[9];
00069             h2 = H[10];
00070             h3 = H[11];
00071             h4 = H[12];
00072             h5 = H[13];
00073             h6 = H[14];
00074             h7 = H[15];     
00075         break;
00076     }
00077 }
00078 
00079 void SHA2_64::update(uint8_t *data, uint32_t length)
00080 {
00081     if((int)length < 128-bufferLength)
00082     {
00083         memcpy(&buffer[bufferLength], data, length);
00084         bufferLength += length;
00085         totalBufferLength += length;
00086         return;
00087     }
00088     int offset = 128-bufferLength;
00089     memcpy(&buffer[bufferLength], data, offset);
00090     computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
00091     while(length-offset > 128)
00092     {
00093         memcpy(buffer, &data[offset], 128);
00094         computeBlock(&h0,&h1,&h2,&h3,&h4,&h5,&h6,&h7,buffer);
00095         offset += 128;
00096     }
00097     if(offset > (int)length)
00098         offset -= 128;
00099     bufferLength = length - offset;
00100     memcpy(buffer, &data[offset], bufferLength);
00101     totalBufferLength += length;
00102 }
00103 
00104 void SHA2_64::finalize(uint8_t *hash)
00105 {
00106     uint64_t *hash2 = (uint64_t*)hash;
00107     uint64_t lengthBit = totalBufferLength << 3;
00108     uint32_t padding;
00109     if(totalBufferLength % 128 < 112)
00110         padding = 112 - (totalBufferLength % 128);
00111     else
00112         padding = 112 + (128 - (totalBufferLength % 128));
00113 
00114     buffer[bufferLength++] = 0x80;
00115     padding--;
00116     if(padding+bufferLength == 112)
00117         memset(&buffer[bufferLength], 0, padding);
00118     else
00119     {
00120         memset(&buffer[bufferLength], 0, 64-bufferLength);
00121         computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
00122         memset(buffer, 0, 112);
00123     }
00124     
00125     lengthBit = revWord(lengthBit);
00126     memcpy(&buffer[120], &lengthBit, 8);    
00127     memset(&buffer[112], 0, 8);    
00128     computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
00129 
00130 
00131     hash2[0] = revWord(h0);
00132     hash2[1] = revWord(h1);
00133     hash2[2] = revWord(h2);
00134     hash2[3] = revWord(h3);
00135     hash2[4] = revWord(h4);
00136     hash2[5] = revWord(h5);
00137 
00138 
00139     if(type == SHA_512)
00140     {
00141         hash2[6] = revWord(h6);
00142         hash2[7] = revWord(h7);
00143     }
00144     
00145     // reset state
00146     switch(type)
00147     {
00148         case SHA_384:
00149             h0 = H[0];
00150             h1 = H[1];
00151             h2 = H[2];
00152             h3 = H[3];
00153             h4 = H[4];
00154             h5 = H[5];
00155             h6 = H[6];
00156             h7 = H[7];
00157         break;
00158         
00159         case SHA_512:
00160             h0 = H[8];
00161             h1 = H[9];
00162             h2 = H[10];
00163             h3 = H[11];
00164             h4 = H[12];
00165             h5 = H[13];
00166             h6 = H[14];
00167             h7 = H[15];     
00168         break;
00169     }
00170     totalBufferLength = 0;
00171     bufferLength = 0;
00172 }
00173 
00174 void SHA2_64::computeHash(SHA2_64_TYPE type, uint8_t *hash, uint8_t *data, uint32_t length)
00175 {
00176     uint64_t *hash2 = (uint64_t*)hash;
00177     uint64_t lengthBit = length * 8;
00178     uint64_t h0 = H[type*8], h1 = H[type*8+1], h2 = H[type*8+2], h3 = H[type*8+3];
00179     uint64_t h4 = H[type*8+4], h5 = H[type*8+5], h6 = H[type*8+6], h7 = H[type*8+7];
00180     
00181     int padding;
00182     if(length % 128 < 112)
00183         padding = 112 - (length % 128);
00184     else
00185         padding = 112 + (128 - (length % 128));
00186         
00187     while(length >= 128)
00188     {
00189         computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, data);
00190         data += 128;
00191         length -= 128;
00192     }
00193     uint8_t buffer[128];
00194     memcpy(buffer, data,length); 
00195     buffer[length] = 0x80;
00196     length++;
00197     padding--;
00198 
00199     if(padding+length == 112)
00200         memset(&buffer[length], 0, padding);
00201     else
00202     {
00203         memset(&buffer[length], 0, 128-length);
00204         computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
00205         memset(buffer, 0, 112);
00206     }
00207     
00208     lengthBit = revWord(lengthBit);
00209     memset(&buffer[112], 0, 8); 
00210     memcpy(&buffer[120], &lengthBit, 8);
00211     computeBlock(&h0, &h1, &h2, &h3, &h4, &h5, &h6, &h7, buffer);
00212 
00213     hash2[0] = revWord(h0);
00214     hash2[1] = revWord(h1);
00215     hash2[2] = revWord(h2);
00216     hash2[3] = revWord(h3);
00217     hash2[4] = revWord(h4);
00218     hash2[5] = revWord(h5);
00219 
00220 
00221     if(type == SHA_512)
00222     {
00223         hash2[6] = revWord(h6);
00224         hash2[7] = revWord(h7);
00225     }
00226 }
00227 
00228 void SHA2_64::computeBlock(uint64_t *h02, 
00229                      uint64_t *h12, 
00230                      uint64_t *h22, 
00231                      uint64_t *h32, 
00232                      uint64_t *h42, 
00233                      uint64_t *h52, 
00234                      uint64_t *h62,
00235                      uint64_t *h72,
00236                      uint8_t *buffer)
00237 {
00238     uint64_t w[80];
00239     uint64_t *buffer2 = (uint64_t*)buffer;
00240 
00241     w[0] = revWord(buffer2[0]);
00242     w[1] = revWord(buffer2[1]);
00243     w[2] = revWord(buffer2[2]);
00244     w[3] = revWord(buffer2[3]);
00245     w[4] = revWord(buffer2[4]);
00246     w[5] = revWord(buffer2[5]);
00247     w[6] = revWord(buffer2[6]);
00248     w[7] = revWord(buffer2[7]); 
00249     w[8] = revWord(buffer2[8]);
00250     w[9] = revWord(buffer2[9]);
00251     w[10] = revWord(buffer2[10]);
00252     w[11] = revWord(buffer2[11]);
00253     w[12] = revWord(buffer2[12]);
00254     w[13] = revWord(buffer2[13]);
00255     w[14] = revWord(buffer2[14]);
00256     w[15] = revWord(buffer2[15]);     
00257     
00258     for(int t = 16; t < 80; ++t)
00259         w[t] = SSIG1(w[t-2]) + w[t-7] + SSIG0(w[t-15]) + w[t-16];
00260     
00261     uint64_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42, f = *h52, g = *h62, h = *h72;
00262     uint64_t T1, T2;
00263     
00264 
00265     R(a,b,c,d,e,f,g,h,0x428a2f98d728ae22,0)
00266     R(h,a,b,c,d,e,f,g,0x7137449123ef65cd,1)
00267     R(g,h,a,b,c,d,e,f,0xb5c0fbcfec4d3b2f,2)
00268     R(f,g,h,a,b,c,d,e,0xe9b5dba58189dbbc,3)
00269     R(e,f,g,h,a,b,c,d,0x3956c25bf348b538,4)
00270     R(d,e,f,g,h,a,b,c,0x59f111f1b605d019,5)
00271     R(c,d,e,f,g,h,a,b,0x923f82a4af194f9b,6)
00272     R(b,c,d,e,f,g,h,a,0xab1c5ed5da6d8118,7)
00273 
00274     R(a,b,c,d,e,f,g,h,0xd807aa98a3030242,8)
00275     R(h,a,b,c,d,e,f,g,0x12835b0145706fbe,9)
00276     R(g,h,a,b,c,d,e,f,0x243185be4ee4b28c,10)
00277     R(f,g,h,a,b,c,d,e,0x550c7dc3d5ffb4e2,11)
00278     R(e,f,g,h,a,b,c,d,0x72be5d74f27b896f,12)
00279     R(d,e,f,g,h,a,b,c,0x80deb1fe3b1696b1,13)
00280     R(c,d,e,f,g,h,a,b,0x9bdc06a725c71235,14)
00281     R(b,c,d,e,f,g,h,a,0xc19bf174cf692694,15)
00282     
00283     
00284     R(a,b,c,d,e,f,g,h,0xe49b69c19ef14ad2,16)
00285     R(h,a,b,c,d,e,f,g,0xefbe4786384f25e3,17)
00286     R(g,h,a,b,c,d,e,f,0x0fc19dc68b8cd5b5,18)
00287     R(f,g,h,a,b,c,d,e,0x240ca1cc77ac9c65,19)
00288     R(e,f,g,h,a,b,c,d,0x2de92c6f592b0275,20)
00289     R(d,e,f,g,h,a,b,c,0x4a7484aa6ea6e483,21)
00290     R(c,d,e,f,g,h,a,b,0x5cb0a9dcbd41fbd4,22)
00291     R(b,c,d,e,f,g,h,a,0x76f988da831153b5,23)
00292     
00293     R(a,b,c,d,e,f,g,h,0x983e5152ee66dfab,24)
00294     R(h,a,b,c,d,e,f,g,0xa831c66d2db43210,25)
00295     R(g,h,a,b,c,d,e,f,0xb00327c898fb213f,26)
00296     R(f,g,h,a,b,c,d,e,0xbf597fc7beef0ee4,27)
00297     R(e,f,g,h,a,b,c,d,0xc6e00bf33da88fc2,28)
00298     R(d,e,f,g,h,a,b,c,0xd5a79147930aa725,29)
00299     R(c,d,e,f,g,h,a,b,0x06ca6351e003826f,30)
00300     R(b,c,d,e,f,g,h,a,0x142929670a0e6e70,31) 
00301     
00302     
00303     R(a,b,c,d,e,f,g,h,0x27b70a8546d22ffc,32)
00304     R(h,a,b,c,d,e,f,g,0x2e1b21385c26c926,33)
00305     R(g,h,a,b,c,d,e,f,0x4d2c6dfc5ac42aed,34)
00306     R(f,g,h,a,b,c,d,e,0x53380d139d95b3df,35)
00307     R(e,f,g,h,a,b,c,d,0x650a73548baf63de,36)
00308     R(d,e,f,g,h,a,b,c,0x766a0abb3c77b2a8,37)
00309     R(c,d,e,f,g,h,a,b,0x81c2c92e47edaee6,38)
00310     R(b,c,d,e,f,g,h,a,0x92722c851482353b,39)
00311     
00312     R(a,b,c,d,e,f,g,h,0xa2bfe8a14cf10364,40)
00313     R(h,a,b,c,d,e,f,g,0xa81a664bbc423001,41)
00314     R(g,h,a,b,c,d,e,f,0xc24b8b70d0f89791,42)
00315     R(f,g,h,a,b,c,d,e,0xc76c51a30654be30,43)
00316     R(e,f,g,h,a,b,c,d,0xd192e819d6ef5218,44)
00317     R(d,e,f,g,h,a,b,c,0xd69906245565a910,45)
00318     R(c,d,e,f,g,h,a,b,0xf40e35855771202a,46)
00319     R(b,c,d,e,f,g,h,a,0x106aa07032bbd1b8,47)
00320 
00321     R(a,b,c,d,e,f,g,h,0x19a4c116b8d2d0c8,48)
00322     R(h,a,b,c,d,e,f,g,0x1e376c085141ab53,49)
00323     R(g,h,a,b,c,d,e,f,0x2748774cdf8eeb99,50)
00324     R(f,g,h,a,b,c,d,e,0x34b0bcb5e19b48a8,51)
00325     R(e,f,g,h,a,b,c,d,0x391c0cb3c5c95a63,52)
00326     R(d,e,f,g,h,a,b,c,0x4ed8aa4ae3418acb,53)
00327     R(c,d,e,f,g,h,a,b,0x5b9cca4f7763e373,54)
00328     R(b,c,d,e,f,g,h,a,0x682e6ff3d6b2b8a3,55)
00329     
00330     R(a,b,c,d,e,f,g,h,0x748f82ee5defb2fc,56)
00331     R(h,a,b,c,d,e,f,g,0x78a5636f43172f60,57)
00332     R(g,h,a,b,c,d,e,f,0x84c87814a1f0ab72,58)
00333     R(f,g,h,a,b,c,d,e,0x8cc702081a6439ec,59)
00334     R(e,f,g,h,a,b,c,d,0x90befffa23631e28,60)
00335     R(d,e,f,g,h,a,b,c,0xa4506cebde82bde9,61)
00336     R(c,d,e,f,g,h,a,b,0xbef9a3f7b2c67915,62)
00337     R(b,c,d,e,f,g,h,a,0xc67178f2e372532b,63)
00338 
00339     R(a,b,c,d,e,f,g,h,0xca273eceea26619c,64)
00340     R(h,a,b,c,d,e,f,g,0xd186b8c721c0c207,65)
00341     R(g,h,a,b,c,d,e,f,0xeada7dd6cde0eb1e,66)
00342     R(f,g,h,a,b,c,d,e,0xf57d4f7fee6ed178,67)
00343     R(e,f,g,h,a,b,c,d,0x06f067aa72176fba,68)
00344     R(d,e,f,g,h,a,b,c,0x0a637dc5a2c898a6,69)
00345     R(c,d,e,f,g,h,a,b,0x113f9804bef90dae,70)
00346     R(b,c,d,e,f,g,h,a,0x1b710b35131c471b,71)
00347 
00348     R(a,b,c,d,e,f,g,h,0x28db77f523047d84,72)
00349     R(h,a,b,c,d,e,f,g,0x32caab7b40c72493,73)
00350     R(g,h,a,b,c,d,e,f,0x3c9ebe0a15c9bebc,74)
00351     R(f,g,h,a,b,c,d,e,0x431d67c49c100d4c,75)
00352     R(e,f,g,h,a,b,c,d,0x4cc5d4becb3e42b6,76)
00353     R(d,e,f,g,h,a,b,c,0x597f299cfc657e2a,77)
00354     R(c,d,e,f,g,h,a,b,0x5fcb6fab3ad6faec,78)
00355     R(b,c,d,e,f,g,h,a,0x6c44198c4a475817,79)
00356             
00357     *h02 += a;
00358     *h12 += b;
00359     *h22 += c;
00360     *h32 += d;
00361     *h42 += e;
00362     *h52 += f;
00363     *h62 += g;
00364     *h72 += h;
00365 }