/** * SHA1 - Secure Hash Algorithm * This code is a direct implementation of the algorithm presented in rfc3174. * No optimizations has been used, although I tried to keep it small in flashsize * It is written in assumption that the target architecture is little endian. */ #include "sha1.h" #define H1 0x67452301 #define H2 0xEFCDAB89 #define H3 0x98BADCFE #define H4 0x10325476 #define H5 0xC3D2E1F0 #define K1 0x5A827999 #define K2 0x6ED9EBA1 #define K3 0x8F1BBCDC #define K4 0xCA62C1D6 #define _LROT32(x,n) (( (uint32_t)(x) << n ) | ( (uint32_t)(x) >>(32-n) )) /*putting this here saves a lot of code space*/ static uint32_t _sha1_chunk[80] __attribute__ ((section (".noinit"))); static uint8_t chunk_cnt __attribute__ ((section (".noinit"))); void sha1_addbyte(uint8_t c){ uint8_t* p=(uint8_t*)_sha1_chunk; uint8_t i=(chunk_cnt & 0x03); /* chunk_cnt-i)+3-i deals with the endianess */ p[(chunk_cnt-i)+3-i]=c; chunk_cnt++; if(chunk_cnt==64){ /*chunk extension*/ uint32_t a,b,c,d,e; for(i=16; i<80; ++i){ _sha1_chunk[i]= _LROT32( _sha1_chunk[i- 3] ^ _sha1_chunk[i- 8] ^ _sha1_chunk[i-14] ^ _sha1_chunk[i-16], 1 ); } a=sha1_digest[4]; b=sha1_digest[3]; c=sha1_digest[2]; d=sha1_digest[1]; e=sha1_digest[0]; /*main loop*/ for(i=0;i<80;i++){ uint32_t f,k,temp; if(i<20){ k=K1; f=(b & c) | ((~b) & d); }else if(i<40){ k=K2; f=b ^ c ^ d; }else if(i<60){ k=K3; f=(b & c) | (b & d) | (c & d); }else{ k=K4; f=b ^ c ^ d; } temp = e + k + f+_LROT32(a,5)+_sha1_chunk[i]; e = d; d = c; c = _LROT32(b,30); b = a; a = temp; } sha1_digest[4]+=a; sha1_digest[3]+=b; sha1_digest[2]+=c; sha1_digest[1]+=d; sha1_digest[0]+=e; chunk_cnt=0; } } void sha1_fill(int32_t len){ /*"append a 1-bit to the message"*/ /*"append 0-bits to the message to obtain a length of len%512=448"*/ /*"append length of message in bits as 64-bit integer"*/ uint8_t j; uint8_t end=(uint8_t)((120-(len-(len/64)*64+1))%64); sha1_addbyte(0x80); for(j=0;j=len){ for(j=0;j