BeRTOS
|
00001 00037 /* 00038 * Derived from: 00039 * SHA-1 in C 00040 * By Steve Reid <steve@edmweb.com> 00041 * 100% Public Domain 00042 */ 00043 00044 /* #define LITTLE_ENDIAN * This should be #define'd if true. */ 00045 /* #define SHA1HANDSOFF * Copies data before messing with it. */ 00046 00047 #include "sha1.h" 00048 00049 #include <cfg/compiler.h> 00050 #include <cfg/debug.h> 00051 #include <cfg/macros.h> 00052 #include <cpu/byteorder.h> // CPU_BYTE_ORDER 00053 #include <string.h> 00054 #include <stdlib.h> 00055 #include <sec/util.h> 00056 00057 #define SHA1_BLOCK_LEN 64 00058 #define SHA1_DIGEST_LEN 20 00059 00060 static void SHA1Transform(uint32_t state[5], const uint8_t buffer[64]); 00061 00062 #define rol(value, bits) ROTL(value, bits) 00063 00064 /* blk0() and blk() perform the initial expand. */ 00065 /* I got the idea of expanding during the round function from SSLeay */ 00066 #define blk0(i) (block[i] = be32_to_cpu(block[i])) 00067 #define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ 00068 ^block[(i+2)&15]^block[i&15],1)) 00069 00070 /* (R0+R1), R2, R3, R4 are the different operations used in SHA1 */ 00071 #define R0(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk0(i)+0x5A827999+rol(v,5);w=rol(w,30); 00072 #define R1(v,w,x,y,z,i) z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=rol(w,30); 00073 #define R2(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=rol(w,30); 00074 #define R3(v,w,x,y,z,i) z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=rol(w,30); 00075 #define R4(v,w,x,y,z,i) z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=rol(w,30); 00076 00077 00078 /* Hash a single 512-bit block. This is the core of the algorithm. */ 00079 static void SHA1Transform(uint32_t state[5], const uint8_t buffer[64]) 00080 { 00081 uint32_t a, b, c, d, e; 00082 uint32_t block[16]; 00083 00084 memcpy(&block, buffer, 64); 00085 00086 /* Copy context->state[] to working vars */ 00087 a = state[0]; 00088 b = state[1]; 00089 c = state[2]; 00090 d = state[3]; 00091 e = state[4]; 00092 /* 4 rounds of 20 operations each. Loop unrolled. */ 00093 R0(a,b,c,d,e, 0); 00094 R0(e,a,b,c,d, 1); 00095 R0(d,e,a,b,c, 2); 00096 R0(c,d,e,a,b, 3); 00097 R0(b,c,d,e,a, 4); 00098 R0(a,b,c,d,e, 5); 00099 R0(e,a,b,c,d, 6); 00100 R0(d,e,a,b,c, 7); 00101 R0(c,d,e,a,b, 8); 00102 R0(b,c,d,e,a, 9); 00103 R0(a,b,c,d,e,10); 00104 R0(e,a,b,c,d,11); 00105 R0(d,e,a,b,c,12); 00106 R0(c,d,e,a,b,13); 00107 R0(b,c,d,e,a,14); 00108 R0(a,b,c,d,e,15); 00109 R1(e,a,b,c,d,16); 00110 R1(d,e,a,b,c,17); 00111 R1(c,d,e,a,b,18); 00112 R1(b,c,d,e,a,19); 00113 R2(a,b,c,d,e,20); 00114 R2(e,a,b,c,d,21); 00115 R2(d,e,a,b,c,22); 00116 R2(c,d,e,a,b,23); 00117 R2(b,c,d,e,a,24); 00118 R2(a,b,c,d,e,25); 00119 R2(e,a,b,c,d,26); 00120 R2(d,e,a,b,c,27); 00121 R2(c,d,e,a,b,28); 00122 R2(b,c,d,e,a,29); 00123 R2(a,b,c,d,e,30); 00124 R2(e,a,b,c,d,31); 00125 R2(d,e,a,b,c,32); 00126 R2(c,d,e,a,b,33); 00127 R2(b,c,d,e,a,34); 00128 R2(a,b,c,d,e,35); 00129 R2(e,a,b,c,d,36); 00130 R2(d,e,a,b,c,37); 00131 R2(c,d,e,a,b,38); 00132 R2(b,c,d,e,a,39); 00133 R3(a,b,c,d,e,40); 00134 R3(e,a,b,c,d,41); 00135 R3(d,e,a,b,c,42); 00136 R3(c,d,e,a,b,43); 00137 R3(b,c,d,e,a,44); 00138 R3(a,b,c,d,e,45); 00139 R3(e,a,b,c,d,46); 00140 R3(d,e,a,b,c,47); 00141 R3(c,d,e,a,b,48); 00142 R3(b,c,d,e,a,49); 00143 R3(a,b,c,d,e,50); 00144 R3(e,a,b,c,d,51); 00145 R3(d,e,a,b,c,52); 00146 R3(c,d,e,a,b,53); 00147 R3(b,c,d,e,a,54); 00148 R3(a,b,c,d,e,55); 00149 R3(e,a,b,c,d,56); 00150 R3(d,e,a,b,c,57); 00151 R3(c,d,e,a,b,58); 00152 R3(b,c,d,e,a,59); 00153 R4(a,b,c,d,e,60); 00154 R4(e,a,b,c,d,61); 00155 R4(d,e,a,b,c,62); 00156 R4(c,d,e,a,b,63); 00157 R4(b,c,d,e,a,64); 00158 R4(a,b,c,d,e,65); 00159 R4(e,a,b,c,d,66); 00160 R4(d,e,a,b,c,67); 00161 R4(c,d,e,a,b,68); 00162 R4(b,c,d,e,a,69); 00163 R4(a,b,c,d,e,70); 00164 R4(e,a,b,c,d,71); 00165 R4(d,e,a,b,c,72); 00166 R4(c,d,e,a,b,73); 00167 R4(b,c,d,e,a,74); 00168 R4(a,b,c,d,e,75); 00169 R4(e,a,b,c,d,76); 00170 R4(d,e,a,b,c,77); 00171 R4(c,d,e,a,b,78); 00172 R4(b,c,d,e,a,79); 00173 /* Add the working vars back into context.state[] */ 00174 state[0] += a; 00175 state[1] += b; 00176 state[2] += c; 00177 state[3] += d; 00178 state[4] += e; 00179 /* Wipe variables */ 00180 a = b = c = d = e = 0; 00181 } 00182 00183 static void SHA1_begin(Hash* h) 00184 { 00185 SHA1_Context *context = (SHA1_Context*)h; 00186 /* SHA1 initialization constants */ 00187 context->state[0] = 0x67452301; 00188 context->state[1] = 0xEFCDAB89; 00189 context->state[2] = 0x98BADCFE; 00190 context->state[3] = 0x10325476; 00191 context->state[4] = 0xC3D2E1F0; 00192 context->count[0] = context->count[1] = 0; 00193 } 00194 00195 /* Run your data through this. */ 00196 00197 static void SHA1_update(Hash* h, const void* vdata, size_t len) 00198 { 00199 SHA1_Context *context = (SHA1_Context*)h; 00200 const uint8_t *data = (const uint8_t*)vdata; 00201 size_t i, j; 00202 00203 j = (context->count[0] >> 3) & 63; 00204 if ((context->count[0] += len << 3) < (len << 3)) 00205 context->count[1]++; 00206 context->count[1] += (len >> 29); 00207 if ((j + len) > 63) { 00208 memcpy(&context->buffer[j], data, (i = 64-j)); 00209 SHA1Transform(context->state, context->buffer); 00210 for ( ; i + 63 < len; i += 64) { 00211 SHA1Transform(context->state, &data[i]); 00212 } 00213 j = 0; 00214 } else 00215 i = 0; 00216 memcpy(&context->buffer[j], &data[i], len - i); 00217 } 00218 00219 00220 /* Add padding and return the message digest. */ 00221 00222 static uint8_t *SHA1_final(Hash* h) 00223 { 00224 SHA1_Context *context = (SHA1_Context*)h; 00225 uint32_t i; 00226 uint8_t finalcount[8]; 00227 00228 for (i = 0; i < 8; i++) 00229 finalcount[i] = (uint8_t)((context->count[(i >= 4 ? 0 : 1)] 00230 >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ 00231 00232 SHA1_update(h, "\200", 1); 00233 while ((context->count[0] & 504) != 448) 00234 SHA1_update(h, "\0", 1); 00235 SHA1_update(h, finalcount, 8); /* Should cause a SHA1Transform() */ 00236 00237 for (i = 0; i < 20; i++) 00238 context->buffer[i] = (uint8_t) 00239 ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); 00240 00241 PURGE(i); 00242 PURGE(finalcount); 00243 return context->buffer; 00244 } 00245 00246 00247 /*************************************************************/ 00248 00249 void SHA1_init(SHA1_Context* ctx) 00250 { 00251 ctx->h.block_len = SHA1_BLOCK_LEN; 00252 ctx->h.digest_len = SHA1_DIGEST_LEN; 00253 ctx->h.begin = SHA1_begin; 00254 ctx->h.update = SHA1_update; 00255 ctx->h.final = SHA1_final; 00256 }