Embedded systems coursework 2.
Fork of Crypto_light by
Embed:
(wiki syntax)
Show/hide line numbers
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 }
Generated on Wed Jul 20 2022 22:55:43 by 1.7.2