/* Implementacija SHA-1 algoritma za izracunavanje sazetka * * (c) Dalibor Dukic duke@x.pbf.hr * Sat Oct 23 13:36:41 CEST 2004 * * algoritam slijedi specifikaciju FIPS 180-1 standard * potpisan od strane NIST-a * */ /* ./sha */ #include #include #include #include #include "Header/sha1.h" /* sha-1 context */ //u_int32_t M[16]; const u_int32_t K[]={ /* Konstante definirane u SHA-1 */ 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x5A827999, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x6ED9EBA1, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0x8F1BBCDC, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, 0xCA62C1D6, }; const u_int32_t H[]={ 0x67452301, 0xEFCDAB89, 0x98BADCFE, 0x10325476, 0xC3D2E1F0 }; /* inicijalizacija konteksta */ void sha1_init(SHA_CTX* sha1_ctx){ sha1_ctx->digest[0]=H[0]; sha1_ctx->digest[1]=H[1]; sha1_ctx->digest[2]=H[2]; sha1_ctx->digest[3]=H[3]; sha1_ctx->digest[4]=H[4]; sha1_ctx->count[0]=0; sha1_ctx->count[1]=0; sha1_ctx->index=0; sha1_ctx->processed=0; } void process_block(SHA_CTX* sha1_ctx, u_int8_t* buffer, unsigned int len ){ int i; memset(&sha1_ctx->M, 0, 64); #ifdef DEBUG fprintf(stdout, "buffer -> %s\n",buffer); fprintf(stdout, "len-> %d\n",len); #endif /* kad dobijemo manji buffer od 64 (64*8)*/ u_int32_t byte; for(i=0; iM[sha1_ctx->index]|=byte; if(sha1_ctx->processed==1) sha1_ctx->processed=0; if((i+1)%4==0) sha1_ctx->index+=1; /* povecaj counter */ sha1_ctx->count[0]+=8; if(sha1_ctx->count[0]==0){ sha1_ctx->count[1]++; // if(sha1_ctx->count[1]==0) // merror("Poruka je predugacka",__LINE__); } if(((i+1)*8)%512==0){ sha1_process_block(sha1_ctx); sha1_ctx->index=0; sha1_ctx->processed=1; memset(&sha1_ctx->M, 0, 64); } } if(len <= BUFFER_LENGTH){ if(sha1_ctx->processed==1) { sha1_ctx->M[sha1_ctx->index]|=0x80000000; sha1_ctx->M[14]=sha1_ctx->count[1]; sha1_ctx->M[15]=sha1_ctx->count[0]; sha1_process_block(sha1_ctx); return; } if((len*8)%512 >447){ if(len%4==1) sha1_ctx->M[sha1_ctx->index-1]|=0x00800000; else if(len%4==2) sha1_ctx->M[sha1_ctx->index-1]|=0x00008000; else if(len%4==3) sha1_ctx->M[sha1_ctx->index-1]|=0x00000080; else if(len%4==0) sha1_ctx->M[sha1_ctx->index]|=0x80000000; sha1_process_block(sha1_ctx); sha1_ctx->index=0; memset(&sha1_ctx->M, 0, 64); sha1_ctx->M[14]=sha1_ctx->count[1]; sha1_ctx->M[15]=sha1_ctx->count[0]; sha1_process_block(sha1_ctx); sha1_ctx->index=0; return; } if(len%4==1) sha1_ctx->M[sha1_ctx->index]|=0x00800000; else if(len%4==2) sha1_ctx->M[sha1_ctx->index]|=0x00008000; else if(len%4==3) sha1_ctx->M[sha1_ctx->index]|=0x00000080; else if(len%4==0) sha1_ctx->M[sha1_ctx->index+1]|=0x80000000; sha1_ctx->M[14]=sha1_ctx->count[1]; sha1_ctx->M[15]=sha1_ctx->count[0]; sha1_process_block(sha1_ctx); sha1_ctx->index=0; } #ifdef DEBUG fprintf(stdout, "i=%d, coun %d-", i,sha1_ctx->count[1]); fprintf(stdout, "%d\n", sha1_ctx->count[0]); #endif } /* f(t;B,C,D) = (B AND C) OR ((NOT B) AND D) ( 0 <= t <= 19) (u C-u: f=(B&C)|((~B)&D) ) f(t;B,C,D) = B XOR C XOR D (20 <= t <= 39) f(t;B,C,D) = (B AND C) OR (B AND D) OR (C AND D) (40 <= t <= 59) f(t;B,C,D) = B XOR C XOR D (60 <= t <= 79). */ u_int32_t f(int t, u_int32_t B, u_int32_t C, u_int32_t D){ u_int32_t buffer; if(0 <= t && t <= 19) buffer=((B & C) | ((~B) & D)); if(20 <= t && t <=39) buffer=(B ^ C ^ D); if(40 <= t && t <= 59) buffer=((B & C)|(B & D)|(C & D)); if(60 <= t && t <= 79) buffer=(B ^ C ^ D); return buffer; } void sha1_process_block(SHA_CTX* sha1_ctx){ u_int32_t W[80]; u_int32_t temp; u_int32_t A,B,C,D,E; int t,j; for(j=0; j<=15; j++){ W[j]=sha1_ctx->M[j]; //W[j]=M[j]; } // W(t)= ROTL_1( W(t-3) XOR W(t-8) XOR W(t-14) XOR W(t-16) ) //ROTL_1 - rotacija 1 mjesto u lijevo for(t=16; t<=79; t++){ W[t]=ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); } A=sha1_ctx->digest[0]; B=sha1_ctx->digest[1]; C=sha1_ctx->digest[2]; D=sha1_ctx->digest[3]; E=sha1_ctx->digest[4]; // TEMP=ROTL_5(A) + f(t;B,C,D) + E + W(t) + K(t) for(t=0; t<=79; t++){ temp=ROTL(5, A) + f(t, B, C, D) + E + W[t] + K[t]; E=D; D=C; C=ROTL(30, B); B=A; A=temp; #ifdef DEBUG fprintf(stdout,"t=%02d %08x %08x %08x %08x %08x\n", t, A, B, C, D, E ); #endif } sha1_ctx->digest[0]+=A; sha1_ctx->digest[1]+=B; sha1_ctx->digest[2]+=C; sha1_ctx->digest[3]+=D; sha1_ctx->digest[4]+=E; }