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