This library implements some hash and cryptographic algorithms.
Dependents: mBuinoBlinky PB_Emma_Ethernet SLOTrashHTTP Garagem ... more
SHA1.cpp
00001 /** 00002 Implementation of SHA-1 as described here: 00003 http://tools.ietf.org/html/rfc1319 00004 */ 00005 00006 #include "SHA1.h" 00007 #include <string.h> 00008 00009 #define F0(B,C,D) ((B & C) | ((~B) & D)) 00010 #define F1(B,C,D) (B ^ C ^ D) 00011 #define F2(B,C,D) ((B & C) | (B & D) | (C & D)) 00012 #define ROTL(W,N) (((W) << N) | ((W) >> (32-N))) 00013 00014 #define K0 0x5A827999 00015 #define K1 0x6ED9EBA1 00016 #define K2 0x8F1BBCDC 00017 #define K3 0xCA62C1D6 00018 00019 00020 #define H0 0x67452301 00021 #define H1 0xEFCDAB89 00022 #define H2 0x98BADCFE 00023 #define H3 0x10325476 00024 #define H4 0xC3D2E1F0 00025 00026 #define MASK 0xF 00027 00028 #define W(s) ( w[s] = ROTL(w[((s) + 13) & MASK] ^ w[((s) + 8) & MASK] ^ w[((s) + 2) & MASK] ^ w[s],1)) 00029 00030 #define R0(A,B,C,D,E,T) E += ROTL(A, 5) + F0(B, C, D) + w[T] + K0; \ 00031 B = ROTL(B,30); 00032 #define R1(A,B,C,D,E,T) E += ROTL(A, 5) + F0(B, C, D) + W(T & MASK) + K0; \ 00033 B = ROTL(B,30); 00034 #define R2(A,B,C,D,E,T) E += ROTL(A, 5) + F1(B, C, D) + W(T & MASK) + K1; \ 00035 B = ROTL(B,30); 00036 #define R3(A,B,C,D,E,T) E += ROTL(A, 5) + F2(B, C, D) + W(T & MASK) + K2; \ 00037 B = ROTL(B,30); 00038 #define R4(A,B,C,D,E,T) E += ROTL(A, 5) + F1(B, C, D) + W(T & MASK) + K3; \ 00039 B = ROTL(B,30); 00040 00041 00042 static uint32_t revWord(const uint32_t w) 00043 { 00044 #ifdef __CC_ARM 00045 return __rev(w); 00046 #else 00047 return (w >> 24) 00048 | ((w & 0x00FF0000) >> 8) 00049 | ((w & 0x0000FF00) << 8) 00050 | ((w & 0x000000FF) << 24); 00051 #endif 00052 } 00053 00054 SHA1::SHA1(): 00055 HashAlgorithm(), 00056 h0(H0), 00057 h1(H1), 00058 h2(H2), 00059 h3(H3), 00060 h4(H4), 00061 totalBufferLength(0), 00062 buffer(), 00063 bufferLength(0) 00064 { 00065 } 00066 00067 uint8_t SHA1::outputSize() const 00068 { 00069 return 20; 00070 } 00071 00072 void SHA1::update(uint8_t *data, uint32_t length) 00073 { 00074 if((int)length < 64-bufferLength) 00075 { 00076 memcpy(&buffer[bufferLength], data, length); 00077 bufferLength += length; 00078 totalBufferLength += length; 00079 return; 00080 } 00081 int offset = 64-bufferLength; 00082 memcpy(&buffer[bufferLength], data, offset); 00083 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); 00084 while(length-offset > 64) 00085 { 00086 memcpy(buffer, &data[offset], 64); 00087 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); 00088 offset += 64; 00089 } 00090 if(offset > (int)length) 00091 offset -= 64; 00092 bufferLength = length - offset; 00093 memcpy(buffer, &data[offset], bufferLength); 00094 totalBufferLength += length; 00095 } 00096 00097 void SHA1::finalize(uint8_t *hash) 00098 { 00099 uint32_t *hash2 = (uint32_t*)hash; 00100 uint16_t padding; 00101 if(totalBufferLength % 64 < 56) 00102 padding = 56 - (totalBufferLength % 64); 00103 else 00104 padding = 56 + (64 - (totalBufferLength % 64)); 00105 00106 buffer[bufferLength++] = 0x80; 00107 padding--; 00108 if(padding+bufferLength == 56) 00109 memset(&buffer[bufferLength], 0, padding); 00110 else 00111 { 00112 memset(&buffer[bufferLength], 0, 64-bufferLength); 00113 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); 00114 memset(buffer, 0, 56); 00115 } 00116 00117 uint64_t lengthBit = totalBufferLength << 3; 00118 uint32_t lengthBitLow = lengthBit; 00119 uint32_t lengthBitHigh = lengthBit >> 32; 00120 lengthBitLow = revWord(lengthBitLow); 00121 lengthBitHigh = revWord(lengthBitHigh); 00122 memcpy(&buffer[56], &lengthBitHigh, 4); 00123 memcpy(&buffer[60], &lengthBitLow, 4); 00124 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); 00125 00126 hash2[0] = revWord(h0); 00127 hash2[1] = revWord(h1); 00128 hash2[2] = revWord(h2); 00129 hash2[3] = revWord(h3); 00130 hash2[4] = revWord(h4); 00131 00132 // reset state 00133 h0 = H0; 00134 h1 = H1; 00135 h2 = H2; 00136 h3 = H3; 00137 h4 = H4; 00138 totalBufferLength = 0; 00139 bufferLength = 0; 00140 } 00141 00142 00143 void SHA1::computeHash(uint8_t *hash, uint8_t *data, uint32_t length) 00144 { 00145 uint32_t *hash2 = (uint32_t*)hash; 00146 uint64_t lengthBit = length << 3; 00147 uint32_t padding; 00148 if(length % 64 < 56) 00149 padding = 56 - (length % 64); 00150 else 00151 padding = 56 + (64 - (length % 64)); 00152 00153 uint32_t h0 = H0, h1 = H1, h2 = H2, h3 = H3, h4 = H4; 00154 while(length >= 64) 00155 { 00156 computeBlock(&h0,&h1,&h2,&h3,&h4, data); 00157 length -= 64; 00158 data += 64; 00159 } 00160 00161 uint8_t buffer[64]; 00162 memcpy(buffer, data, length); 00163 buffer[length++] = 0x80; 00164 padding--; 00165 if(padding+length+8 == 64) 00166 memset(&buffer[length], 0, padding); 00167 else 00168 { 00169 memset(&buffer[length], 0, 64-length); 00170 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); 00171 memset(buffer, 0, 56); 00172 } 00173 00174 uint32_t lengthBitLow = lengthBit; 00175 uint32_t lengthBitHigh = lengthBit >> 32; 00176 lengthBitLow = revWord(lengthBitLow); 00177 lengthBitHigh = revWord(lengthBitHigh); 00178 memcpy(&buffer[60], &lengthBitLow, 4); 00179 memcpy(&buffer[56], &lengthBitHigh, 4); 00180 00181 computeBlock(&h0,&h1,&h2,&h3,&h4, buffer); 00182 00183 hash2[0] = revWord(h0); 00184 hash2[1] = revWord(h1); 00185 hash2[2] = revWord(h2); 00186 hash2[3] = revWord(h3); 00187 hash2[4] = revWord(h4); 00188 } 00189 00190 void SHA1::computeBlock(uint32_t *h02, uint32_t *h12, uint32_t *h22, uint32_t *h32, uint32_t *h42, uint8_t *buffer) 00191 { 00192 uint32_t *buffer2 = (uint32_t*)buffer; 00193 uint32_t w[16]; 00194 00195 for(int t = 0; t < 16; ++t) 00196 w[t] = revWord(buffer2[t]); 00197 00198 uint32_t a = *h02, b = *h12, c = *h22, d = *h32, e = *h42; 00199 00200 R0(a,b,c,d,e, 0) R0(e,a,b,c,d, 1) R0(d,e,a,b,c, 2) R0(c,d,e,a,b, 3) 00201 R0(b,c,d,e,a, 4) R0(a,b,c,d,e, 5) R0(e,a,b,c,d, 6) R0(d,e,a,b,c, 7) 00202 R0(c,d,e,a,b, 8) R0(b,c,d,e,a, 9) R0(a,b,c,d,e,10) R0(e,a,b,c,d,11) 00203 R0(d,e,a,b,c,12) R0(c,d,e,a,b,13) R0(b,c,d,e,a,14) R0(a,b,c,d,e,15) 00204 R1(e,a,b,c,d,16) R1(d,e,a,b,c,17) R1(c,d,e,a,b,18) R1(b,c,d,e,a,19) 00205 00206 00207 R2(a,b,c,d,e,20) R2(e,a,b,c,d,21) R2(d,e,a,b,c,22) R2(c,d,e,a,b,23) 00208 R2(b,c,d,e,a,24) R2(a,b,c,d,e,25) R2(e,a,b,c,d,26) R2(d,e,a,b,c,27) 00209 R2(c,d,e,a,b,28) R2(b,c,d,e,a,29) R2(a,b,c,d,e,30) R2(e,a,b,c,d,31) 00210 R2(d,e,a,b,c,32) R2(c,d,e,a,b,33) R2(b,c,d,e,a,34) R2(a,b,c,d,e,35) 00211 R2(e,a,b,c,d,36) R2(d,e,a,b,c,37) R2(c,d,e,a,b,38) R2(b,c,d,e,a,39) 00212 00213 R3(a,b,c,d,e,40) R3(e,a,b,c,d,41) R3(d,e,a,b,c,42) R3(c,d,e,a,b,43) 00214 R3(b,c,d,e,a,44) R3(a,b,c,d,e,45) R3(e,a,b,c,d,46) R3(d,e,a,b,c,47) 00215 R3(c,d,e,a,b,48) R3(b,c,d,e,a,49) R3(a,b,c,d,e,50) R3(e,a,b,c,d,51) 00216 R3(d,e,a,b,c,52) R3(c,d,e,a,b,53) R3(b,c,d,e,a,54) R3(a,b,c,d,e,55) 00217 R3(e,a,b,c,d,56) R3(d,e,a,b,c,57) R3(c,d,e,a,b,58) R3(b,c,d,e,a,59) 00218 00219 00220 R4(a,b,c,d,e,60) R4(e,a,b,c,d,61) R4(d,e,a,b,c,62) R4(c,d,e,a,b,63) 00221 R4(b,c,d,e,a,64) R4(a,b,c,d,e,65) R4(e,a,b,c,d,66) R4(d,e,a,b,c,67) 00222 R4(c,d,e,a,b,68) R4(b,c,d,e,a,69) R4(a,b,c,d,e,70) R4(e,a,b,c,d,71) 00223 R4(d,e,a,b,c,72) R4(c,d,e,a,b,73) R4(b,c,d,e,a,74) R4(a,b,c,d,e,75) 00224 R4(e,a,b,c,d,76) R4(d,e,a,b,c,77) R4(c,d,e,a,b,78) R4(b,c,d,e,a,79) 00225 00226 *h02 += a; 00227 *h12 += b; 00228 *h22 += c; 00229 *h32 += d; 00230 *h42 += e; 00231 }
Generated on Tue Jul 12 2022 18:54:16 by 1.7.2