00001 
00016 #include "includes.h"
00017 
00018 #include "common.h"
00019 #include "sha1.h"
00020 #include "sha1_i.h"
00021 #include "md5.h"
00022 #include "crypto.h"
00023 
00024 typedef struct SHA1Context SHA1_CTX;
00025 
00026 void SHA1Transform(u32 state[5], const unsigned char buffer[64]);
00027 
00028 
00038 int sha1_vector(size_t num_elem, const u8 *addr[], const size_t *len, u8 *mac)
00039 {
00040         SHA1_CTX ctx;
00041         size_t i;
00042 
00043         SHA1Init(&ctx);
00044         for (i = 0; i < num_elem; i++)
00045                 SHA1Update(&ctx, addr[i], len[i]);
00046         SHA1Final(mac, &ctx);
00047         return 0;
00048 }
00049 
00050 
00051 
00052 
00053 
00054 
00055 
00056 
00057 
00058 
00059 
00060 
00061 
00062 
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 
00076 
00077 
00078 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00086 
00087 
00088 
00089 
00090 
00091 
00092 
00093 
00094 
00095 
00096 
00097 
00098 
00099 
00100 
00101 
00102 
00103 
00104 
00105 
00106 
00107 
00108 
00109 
00110 
00111 
00112 
00113 
00114 
00115 
00116 
00117 
00118 
00119 
00120 
00121 
00122 
00123 
00124 
00125 
00126 
00127 
00128 
00129 
00130 
00131 #define SHA1HANDSOFF
00132 
00133 #define rol(value, bits) (((value) << (bits)) | ((value) >> (32 - (bits))))
00134 
00135 
00136 
00137 #ifndef WORDS_BIGENDIAN
00138 #define blk0(i) (block->l[i] = (rol(block->l[i], 24) & 0xFF00FF00) | \
00139         (rol(block->l[i], 8) & 0x00FF00FF))
00140 #else
00141 #define blk0(i) block->l[i]
00142 #endif
00143 #define blk(i) (block->l[i & 15] = rol(block->l[(i + 13) & 15] ^ \
00144         block->l[(i + 8) & 15] ^ block->l[(i + 2) & 15] ^ block->l[i & 15], 1))
00145 
00146 
00147 #define R0(v,w,x,y,z,i) \
00148         z += ((w & (x ^ y)) ^ y) + blk0(i) + 0x5A827999 + rol(v, 5); \
00149         w = rol(w, 30);
00150 #define R1(v,w,x,y,z,i) \
00151         z += ((w & (x ^ y)) ^ y) + blk(i) + 0x5A827999 + rol(v, 5); \
00152         w = rol(w, 30);
00153 #define R2(v,w,x,y,z,i) \
00154         z += (w ^ x ^ y) + blk(i) + 0x6ED9EBA1 + rol(v, 5); w = rol(w, 30);
00155 #define R3(v,w,x,y,z,i) \
00156         z += (((w | x) & y) | (w & x)) + blk(i) + 0x8F1BBCDC + rol(v, 5); \
00157         w = rol(w, 30);
00158 #define R4(v,w,x,y,z,i) \
00159         z += (w ^ x ^ y) + blk(i) + 0xCA62C1D6 + rol(v, 5); \
00160         w=rol(w, 30);
00161 
00162 
00163 #ifdef VERBOSE  
00164 void SHAPrintContext(SHA1_CTX *context, char *msg)
00165 {
00166         printf("%s (%d,%d) %x %x %x %x %x\n",
00167                msg,
00168                context->count[0], context->count[1], 
00169                context->state[0],
00170                context->state[1],
00171                context->state[2],
00172                context->state[3],
00173                context->state[4]);
00174 }
00175 #endif
00176 
00177 
00178 
00179 void SHA1Transform(u32 state[5], const unsigned char buffer[64])
00180 {
00181         u32 a, b, c, d, e;
00182         typedef union {
00183                 unsigned char c[64];
00184                 u32 l[16];
00185         } CHAR64LONG16;
00186         CHAR64LONG16* block;
00187 #ifdef SHA1HANDSOFF
00188         CHAR64LONG16 workspace;
00189         block = &workspace;
00190         os_memcpy(block, buffer, 64);
00191 #else
00192         block = (CHAR64LONG16 *) buffer;
00193 #endif
00194         
00195         a = state[0];
00196         b = state[1];
00197         c = state[2];
00198         d = state[3];
00199         e = state[4];
00200         
00201         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);
00202         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);
00203         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);
00204         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);
00205         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);
00206         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);
00207         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);
00208         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);
00209         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);
00210         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);
00211         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);
00212         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);
00213         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);
00214         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);
00215         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);
00216         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);
00217         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);
00218         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);
00219         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);
00220         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);
00221         
00222         state[0] += a;
00223         state[1] += b;
00224         state[2] += c;
00225         state[3] += d;
00226         state[4] += e;
00227         
00228         a = b = c = d = e = 0;
00229 #ifdef SHA1HANDSOFF
00230         os_memset(block, 0, 64);
00231 #endif
00232 }
00233 
00234 
00235 
00236 
00237 void SHA1Init(SHA1_CTX* context)
00238 {
00239         
00240         context->state[0] = 0x67452301;
00241         context->state[1] = 0xEFCDAB89;
00242         context->state[2] = 0x98BADCFE;
00243         context->state[3] = 0x10325476;
00244         context->state[4] = 0xC3D2E1F0;
00245         context->count[0] = context->count[1] = 0;
00246 }
00247 
00248 
00249 
00250 
00251 void SHA1Update(SHA1_CTX* context, const void *_data, u32 len)
00252 {
00253         u32 i, j;
00254         const unsigned char *data = _data;
00255 
00256 #ifdef VERBOSE
00257         SHAPrintContext(context, "before");
00258 #endif
00259         j = (context->count[0] >> 3) & 63;
00260         if ((context->count[0] += len << 3) < (len << 3))
00261                 context->count[1]++;
00262         context->count[1] += (len >> 29);
00263         if ((j + len) > 63) {
00264                 os_memcpy(&context->buffer[j], data, (i = 64-j));
00265                 SHA1Transform(context->state, context->buffer);
00266                 for ( ; i + 63 < len; i += 64) {
00267                         SHA1Transform(context->state, &data[i]);
00268                 }
00269                 j = 0;
00270         }
00271         else i = 0;
00272         os_memcpy(&context->buffer[j], &data[i], len - i);
00273 #ifdef VERBOSE
00274         SHAPrintContext(context, "after ");
00275 #endif
00276 }
00277 
00278 
00279 
00280 
00281 void SHA1Final(unsigned char digest[20], SHA1_CTX* context)
00282 {
00283         u32 i;
00284         unsigned char finalcount[8];
00285 
00286         for (i = 0; i < 8; i++) {
00287                 finalcount[i] = (unsigned char)
00288                         ((context->count[(i >= 4 ? 0 : 1)] >>
00289                           ((3-(i & 3)) * 8) ) & 255);  
00290         }
00291         SHA1Update(context, (unsigned char *) "\200", 1);
00292         while ((context->count[0] & 504) != 448) {
00293                 SHA1Update(context, (unsigned char *) "\0", 1);
00294         }
00295         SHA1Update(context, finalcount, 8);  
00296 
00297         for (i = 0; i < 20; i++) {
00298                 digest[i] = (unsigned char)
00299                         ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) &
00300                          255);
00301         }
00302         
00303         i = 0;
00304         os_memset(context->buffer, 0, 64);
00305         os_memset(context->state, 0, 20);
00306         os_memset(context->count, 0, 8);
00307         os_memset(finalcount, 0, 8);
00308 }
00309 
00310 
00311