more handlers

Dependents:   bandwidth-meter-net mbedRail24v

Fork of Tiny-HTTPD by ban4jp -

Committer:
Jasper
Date:
Fri May 30 03:55:43 2014 +0000
Revision:
3:145c65ab9805
Parent:
0:d18dff347122
NULL isn't always 0, we need more handlers

Who changed what in which revision?

UserRevisionLine numberNew contents of line
okini3939 0:d18dff347122 1 /*
okini3939 0:d18dff347122 2 * source from http://www.ipa.go.jp/security/rfc/RFC3174JA.html
okini3939 0:d18dff347122 3 */
okini3939 0:d18dff347122 4 #include "sha1.h"
okini3939 0:d18dff347122 5
okini3939 0:d18dff347122 6 /*
okini3939 0:d18dff347122 7 * Define the SHA1 circular left shift macro
okini3939 0:d18dff347122 8 */
okini3939 0:d18dff347122 9 #define SHA1CircularShift(bits,word) \
okini3939 0:d18dff347122 10 (((word) << (bits)) | ((word) >> (32-(bits))))
okini3939 0:d18dff347122 11
okini3939 0:d18dff347122 12 /* Local Function Prototyptes */
okini3939 0:d18dff347122 13 void SHA1PadMessage(SHA1Context *);
okini3939 0:d18dff347122 14 void SHA1ProcessMessageBlock(SHA1Context *);
okini3939 0:d18dff347122 15
okini3939 0:d18dff347122 16 /*
okini3939 0:d18dff347122 17 * SHA1Reset
okini3939 0:d18dff347122 18 *
okini3939 0:d18dff347122 19 * Description:
okini3939 0:d18dff347122 20 * This function will initialize the SHA1Context in preparation
okini3939 0:d18dff347122 21 * for computing a new SHA1 message digest.
okini3939 0:d18dff347122 22 *
okini3939 0:d18dff347122 23 * Parameters:
okini3939 0:d18dff347122 24 * context: [in/out]
okini3939 0:d18dff347122 25 * The context to reset.
okini3939 0:d18dff347122 26 *
okini3939 0:d18dff347122 27 * Returns:
okini3939 0:d18dff347122 28 * sha Error Code.
okini3939 0:d18dff347122 29 *
okini3939 0:d18dff347122 30 */
okini3939 0:d18dff347122 31 int SHA1Reset(SHA1Context *context)
okini3939 0:d18dff347122 32 {
okini3939 0:d18dff347122 33 if (!context)
okini3939 0:d18dff347122 34 {
okini3939 0:d18dff347122 35 return shaNull;
okini3939 0:d18dff347122 36 }
okini3939 0:d18dff347122 37
okini3939 0:d18dff347122 38 context->Length_Low = 0;
okini3939 0:d18dff347122 39 context->Length_High = 0;
okini3939 0:d18dff347122 40 context->Message_Block_Index = 0;
okini3939 0:d18dff347122 41
okini3939 0:d18dff347122 42 context->Intermediate_Hash[0] = 0x67452301;
okini3939 0:d18dff347122 43 context->Intermediate_Hash[1] = 0xEFCDAB89;
okini3939 0:d18dff347122 44 context->Intermediate_Hash[2] = 0x98BADCFE;
okini3939 0:d18dff347122 45 context->Intermediate_Hash[3] = 0x10325476;
okini3939 0:d18dff347122 46 context->Intermediate_Hash[4] = 0xC3D2E1F0;
okini3939 0:d18dff347122 47
okini3939 0:d18dff347122 48 context->Computed = 0;
okini3939 0:d18dff347122 49 context->Corrupted = 0;
okini3939 0:d18dff347122 50
okini3939 0:d18dff347122 51 return shaSuccess;
okini3939 0:d18dff347122 52 }
okini3939 0:d18dff347122 53
okini3939 0:d18dff347122 54 /*
okini3939 0:d18dff347122 55 * SHA1Result
okini3939 0:d18dff347122 56 *
okini3939 0:d18dff347122 57 * Description:
okini3939 0:d18dff347122 58 * This function will return the 160-bit message digest into the
okini3939 0:d18dff347122 59 * Message_Digest array provided by the caller.
okini3939 0:d18dff347122 60 * NOTE: The first octet of hash is stored in the 0th element,
okini3939 0:d18dff347122 61 * the last octet of hash in the 19th element.
okini3939 0:d18dff347122 62 *
okini3939 0:d18dff347122 63 * Parameters:
okini3939 0:d18dff347122 64 * context: [in/out]
okini3939 0:d18dff347122 65 * The context to use to calculate the SHA-1 hash.
okini3939 0:d18dff347122 66 * Message_Digest: [out]
okini3939 0:d18dff347122 67 * Where the digest is returned.
okini3939 0:d18dff347122 68 *
okini3939 0:d18dff347122 69 * Returns:
okini3939 0:d18dff347122 70 * sha Error Code.
okini3939 0:d18dff347122 71 *
okini3939 0:d18dff347122 72 */
okini3939 0:d18dff347122 73 int SHA1Result( SHA1Context *context,
okini3939 0:d18dff347122 74 uint8_t Message_Digest[SHA1HashSize])
okini3939 0:d18dff347122 75 {
okini3939 0:d18dff347122 76 int i;
okini3939 0:d18dff347122 77
okini3939 0:d18dff347122 78 if (!context || !Message_Digest)
okini3939 0:d18dff347122 79 {
okini3939 0:d18dff347122 80 return shaNull;
okini3939 0:d18dff347122 81 }
okini3939 0:d18dff347122 82
okini3939 0:d18dff347122 83 if (context->Corrupted)
okini3939 0:d18dff347122 84 {
okini3939 0:d18dff347122 85 return context->Corrupted;
okini3939 0:d18dff347122 86 }
okini3939 0:d18dff347122 87
okini3939 0:d18dff347122 88 if (!context->Computed)
okini3939 0:d18dff347122 89 {
okini3939 0:d18dff347122 90 SHA1PadMessage(context);
okini3939 0:d18dff347122 91 for(i=0; i<64; ++i)
okini3939 0:d18dff347122 92 {
okini3939 0:d18dff347122 93 /* message may be sensitive, clear it out */
okini3939 0:d18dff347122 94 context->Message_Block[i] = 0;
okini3939 0:d18dff347122 95 }
okini3939 0:d18dff347122 96 context->Length_Low = 0; /* and clear length */
okini3939 0:d18dff347122 97 context->Length_High = 0;
okini3939 0:d18dff347122 98 context->Computed = 1;
okini3939 0:d18dff347122 99 }
okini3939 0:d18dff347122 100
okini3939 0:d18dff347122 101 for(i = 0; i < SHA1HashSize; ++i)
okini3939 0:d18dff347122 102 {
okini3939 0:d18dff347122 103 Message_Digest[i] = context->Intermediate_Hash[i>>2]
okini3939 0:d18dff347122 104 >> 8 * ( 3 - ( i & 0x03 ) );
okini3939 0:d18dff347122 105 }
okini3939 0:d18dff347122 106
okini3939 0:d18dff347122 107 return shaSuccess;
okini3939 0:d18dff347122 108 }
okini3939 0:d18dff347122 109
okini3939 0:d18dff347122 110 /*
okini3939 0:d18dff347122 111 * SHA1Input
okini3939 0:d18dff347122 112 *
okini3939 0:d18dff347122 113 * Description:
okini3939 0:d18dff347122 114 * This function accepts an array of octets as the next portion
okini3939 0:d18dff347122 115 * of the message.
okini3939 0:d18dff347122 116 *
okini3939 0:d18dff347122 117 * Parameters:
okini3939 0:d18dff347122 118 * context: [in/out]
okini3939 0:d18dff347122 119 * The SHA context to update
okini3939 0:d18dff347122 120 * message_array: [in]
okini3939 0:d18dff347122 121 * An array of characters representing the next portion of
okini3939 0:d18dff347122 122 * the message.
okini3939 0:d18dff347122 123 * length: [in]
okini3939 0:d18dff347122 124 * The length of the message in message_array
okini3939 0:d18dff347122 125 *
okini3939 0:d18dff347122 126 * Returns:
okini3939 0:d18dff347122 127 * sha Error Code.
okini3939 0:d18dff347122 128 *
okini3939 0:d18dff347122 129 */
okini3939 0:d18dff347122 130 int SHA1Input( SHA1Context *context,
okini3939 0:d18dff347122 131 const uint8_t *message_array,
okini3939 0:d18dff347122 132 unsigned length)
okini3939 0:d18dff347122 133 {
okini3939 0:d18dff347122 134 if (!length)
okini3939 0:d18dff347122 135 {
okini3939 0:d18dff347122 136 return shaSuccess;
okini3939 0:d18dff347122 137 }
okini3939 0:d18dff347122 138
okini3939 0:d18dff347122 139 if (!context || !message_array)
okini3939 0:d18dff347122 140 {
okini3939 0:d18dff347122 141 return shaNull;
okini3939 0:d18dff347122 142 }
okini3939 0:d18dff347122 143
okini3939 0:d18dff347122 144 if (context->Computed)
okini3939 0:d18dff347122 145 {
okini3939 0:d18dff347122 146 context->Corrupted = shaStateError;
okini3939 0:d18dff347122 147 return shaStateError;
okini3939 0:d18dff347122 148 }
okini3939 0:d18dff347122 149
okini3939 0:d18dff347122 150 if (context->Corrupted)
okini3939 0:d18dff347122 151 {
okini3939 0:d18dff347122 152 return context->Corrupted;
okini3939 0:d18dff347122 153 }
okini3939 0:d18dff347122 154 while(length-- && !context->Corrupted)
okini3939 0:d18dff347122 155 {
okini3939 0:d18dff347122 156 context->Message_Block[context->Message_Block_Index++] =
okini3939 0:d18dff347122 157 (*message_array & 0xFF);
okini3939 0:d18dff347122 158
okini3939 0:d18dff347122 159 context->Length_Low += 8;
okini3939 0:d18dff347122 160 if (context->Length_Low == 0)
okini3939 0:d18dff347122 161 {
okini3939 0:d18dff347122 162 context->Length_High++;
okini3939 0:d18dff347122 163 if (context->Length_High == 0)
okini3939 0:d18dff347122 164 {
okini3939 0:d18dff347122 165 /* Message is too long */
okini3939 0:d18dff347122 166 context->Corrupted = 1;
okini3939 0:d18dff347122 167 }
okini3939 0:d18dff347122 168 }
okini3939 0:d18dff347122 169
okini3939 0:d18dff347122 170 if (context->Message_Block_Index == 64)
okini3939 0:d18dff347122 171 {
okini3939 0:d18dff347122 172 SHA1ProcessMessageBlock(context);
okini3939 0:d18dff347122 173 }
okini3939 0:d18dff347122 174
okini3939 0:d18dff347122 175 message_array++;
okini3939 0:d18dff347122 176 }
okini3939 0:d18dff347122 177
okini3939 0:d18dff347122 178 return shaSuccess;
okini3939 0:d18dff347122 179 }
okini3939 0:d18dff347122 180
okini3939 0:d18dff347122 181 /*
okini3939 0:d18dff347122 182 * SHA1ProcessMessageBlock
okini3939 0:d18dff347122 183 *
okini3939 0:d18dff347122 184 * Description:
okini3939 0:d18dff347122 185 * This function will process the next 512 bits of the message
okini3939 0:d18dff347122 186 * stored in the Message_Block array.
okini3939 0:d18dff347122 187 *
okini3939 0:d18dff347122 188 * Parameters:
okini3939 0:d18dff347122 189 * None.
okini3939 0:d18dff347122 190 *
okini3939 0:d18dff347122 191 * Returns:
okini3939 0:d18dff347122 192 * Nothing.
okini3939 0:d18dff347122 193 *
okini3939 0:d18dff347122 194 * Comments:
okini3939 0:d18dff347122 195 * Many of the variable names in this code, especially the
okini3939 0:d18dff347122 196 * single character names, were used because those were the
okini3939 0:d18dff347122 197 * names used in the publication.
okini3939 0:d18dff347122 198 *
okini3939 0:d18dff347122 199 *
okini3939 0:d18dff347122 200 */
okini3939 0:d18dff347122 201 void SHA1ProcessMessageBlock(SHA1Context *context)
okini3939 0:d18dff347122 202 {
okini3939 0:d18dff347122 203 const uint32_t K[] = { /* Constants defined in SHA-1 */
okini3939 0:d18dff347122 204 0x5A827999,
okini3939 0:d18dff347122 205 0x6ED9EBA1,
okini3939 0:d18dff347122 206 0x8F1BBCDC,
okini3939 0:d18dff347122 207 0xCA62C1D6
okini3939 0:d18dff347122 208 };
okini3939 0:d18dff347122 209 int t; /* Loop counter */
okini3939 0:d18dff347122 210 uint32_t temp; /* Temporary word value */
okini3939 0:d18dff347122 211 uint32_t W[80]; /* Word sequence */
okini3939 0:d18dff347122 212 uint32_t A, B, C, D, E; /* Word buffers */
okini3939 0:d18dff347122 213
okini3939 0:d18dff347122 214 /*
okini3939 0:d18dff347122 215 * Initialize the first 16 words in the array W
okini3939 0:d18dff347122 216 */
okini3939 0:d18dff347122 217 for(t = 0; t < 16; t++)
okini3939 0:d18dff347122 218 {
okini3939 0:d18dff347122 219 W[t] = context->Message_Block[t * 4] << 24;
okini3939 0:d18dff347122 220 W[t] |= context->Message_Block[t * 4 + 1] << 16;
okini3939 0:d18dff347122 221 W[t] |= context->Message_Block[t * 4 + 2] << 8;
okini3939 0:d18dff347122 222 W[t] |= context->Message_Block[t * 4 + 3];
okini3939 0:d18dff347122 223 }
okini3939 0:d18dff347122 224
okini3939 0:d18dff347122 225 for(t = 16; t < 80; t++)
okini3939 0:d18dff347122 226 {
okini3939 0:d18dff347122 227 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
okini3939 0:d18dff347122 228 }
okini3939 0:d18dff347122 229
okini3939 0:d18dff347122 230 A = context->Intermediate_Hash[0];
okini3939 0:d18dff347122 231 B = context->Intermediate_Hash[1];
okini3939 0:d18dff347122 232 C = context->Intermediate_Hash[2];
okini3939 0:d18dff347122 233 D = context->Intermediate_Hash[3];
okini3939 0:d18dff347122 234 E = context->Intermediate_Hash[4];
okini3939 0:d18dff347122 235
okini3939 0:d18dff347122 236 for(t = 0; t < 20; t++)
okini3939 0:d18dff347122 237 {
okini3939 0:d18dff347122 238 temp = SHA1CircularShift(5,A) +
okini3939 0:d18dff347122 239 ((B & C) | ((~B) & D)) + E + W[t] + K[0];
okini3939 0:d18dff347122 240 E = D;
okini3939 0:d18dff347122 241 D = C;
okini3939 0:d18dff347122 242 C = SHA1CircularShift(30,B);
okini3939 0:d18dff347122 243 B = A;
okini3939 0:d18dff347122 244 A = temp;
okini3939 0:d18dff347122 245 }
okini3939 0:d18dff347122 246
okini3939 0:d18dff347122 247 for(t = 20; t < 40; t++)
okini3939 0:d18dff347122 248 {
okini3939 0:d18dff347122 249 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
okini3939 0:d18dff347122 250 E = D;
okini3939 0:d18dff347122 251 D = C;
okini3939 0:d18dff347122 252 C = SHA1CircularShift(30,B);
okini3939 0:d18dff347122 253 B = A;
okini3939 0:d18dff347122 254 A = temp;
okini3939 0:d18dff347122 255 }
okini3939 0:d18dff347122 256
okini3939 0:d18dff347122 257 for(t = 40; t < 60; t++)
okini3939 0:d18dff347122 258 {
okini3939 0:d18dff347122 259 temp = SHA1CircularShift(5,A) +
okini3939 0:d18dff347122 260 ((B & C) | (B & D) | (C & D)) + E + W[t] + K[2];
okini3939 0:d18dff347122 261 E = D;
okini3939 0:d18dff347122 262 D = C;
okini3939 0:d18dff347122 263 C = SHA1CircularShift(30,B);
okini3939 0:d18dff347122 264 B = A;
okini3939 0:d18dff347122 265 A = temp;
okini3939 0:d18dff347122 266 }
okini3939 0:d18dff347122 267
okini3939 0:d18dff347122 268 for(t = 60; t < 80; t++)
okini3939 0:d18dff347122 269 {
okini3939 0:d18dff347122 270 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
okini3939 0:d18dff347122 271 E = D;
okini3939 0:d18dff347122 272 D = C;
okini3939 0:d18dff347122 273 C = SHA1CircularShift(30,B);
okini3939 0:d18dff347122 274 B = A;
okini3939 0:d18dff347122 275 A = temp;
okini3939 0:d18dff347122 276 }
okini3939 0:d18dff347122 277
okini3939 0:d18dff347122 278 context->Intermediate_Hash[0] += A;
okini3939 0:d18dff347122 279 context->Intermediate_Hash[1] += B;
okini3939 0:d18dff347122 280 context->Intermediate_Hash[2] += C;
okini3939 0:d18dff347122 281 context->Intermediate_Hash[3] += D;
okini3939 0:d18dff347122 282 context->Intermediate_Hash[4] += E;
okini3939 0:d18dff347122 283
okini3939 0:d18dff347122 284 context->Message_Block_Index = 0;
okini3939 0:d18dff347122 285 }
okini3939 0:d18dff347122 286
okini3939 0:d18dff347122 287
okini3939 0:d18dff347122 288 /*
okini3939 0:d18dff347122 289 * SHA1PadMessage
okini3939 0:d18dff347122 290 *
okini3939 0:d18dff347122 291 * Description:
okini3939 0:d18dff347122 292 * According to the standard, the message must be padded to an even
okini3939 0:d18dff347122 293 * 512 bits. The first padding bit must be a '1'. The last 64
okini3939 0:d18dff347122 294 * bits represent the length of the original message. All bits in
okini3939 0:d18dff347122 295 * between should be 0. This function will pad the message
okini3939 0:d18dff347122 296 * according to those rules by filling the Message_Block array
okini3939 0:d18dff347122 297 * accordingly. It will also call the ProcessMessageBlock function
okini3939 0:d18dff347122 298 * provided appropriately. When it returns, it can be assumed that
okini3939 0:d18dff347122 299 * the message digest has been computed.
okini3939 0:d18dff347122 300 *
okini3939 0:d18dff347122 301 * Parameters:
okini3939 0:d18dff347122 302 * context: [in/out]
okini3939 0:d18dff347122 303 * The context to pad
okini3939 0:d18dff347122 304 * ProcessMessageBlock: [in]
okini3939 0:d18dff347122 305 * The appropriate SHA*ProcessMessageBlock function
okini3939 0:d18dff347122 306 * Returns:
okini3939 0:d18dff347122 307 * Nothing.
okini3939 0:d18dff347122 308 *
okini3939 0:d18dff347122 309 */
okini3939 0:d18dff347122 310
okini3939 0:d18dff347122 311 void SHA1PadMessage(SHA1Context *context)
okini3939 0:d18dff347122 312 {
okini3939 0:d18dff347122 313 /*
okini3939 0:d18dff347122 314 * Check to see if the current message block is too small to hold
okini3939 0:d18dff347122 315 * the initial padding bits and length. If so, we will pad the
okini3939 0:d18dff347122 316 * block, process it, and then continue padding into a second
okini3939 0:d18dff347122 317 * block.
okini3939 0:d18dff347122 318 */
okini3939 0:d18dff347122 319 if (context->Message_Block_Index > 55)
okini3939 0:d18dff347122 320 {
okini3939 0:d18dff347122 321 context->Message_Block[context->Message_Block_Index++] = 0x80;
okini3939 0:d18dff347122 322 while(context->Message_Block_Index < 64)
okini3939 0:d18dff347122 323 {
okini3939 0:d18dff347122 324 context->Message_Block[context->Message_Block_Index++] = 0;
okini3939 0:d18dff347122 325 }
okini3939 0:d18dff347122 326
okini3939 0:d18dff347122 327 SHA1ProcessMessageBlock(context);
okini3939 0:d18dff347122 328
okini3939 0:d18dff347122 329 while(context->Message_Block_Index < 56)
okini3939 0:d18dff347122 330 {
okini3939 0:d18dff347122 331 context->Message_Block[context->Message_Block_Index++] = 0;
okini3939 0:d18dff347122 332 }
okini3939 0:d18dff347122 333 }
okini3939 0:d18dff347122 334 else
okini3939 0:d18dff347122 335 {
okini3939 0:d18dff347122 336 context->Message_Block[context->Message_Block_Index++] = 0x80;
okini3939 0:d18dff347122 337 while(context->Message_Block_Index < 56)
okini3939 0:d18dff347122 338 {
okini3939 0:d18dff347122 339 context->Message_Block[context->Message_Block_Index++] = 0;
okini3939 0:d18dff347122 340 }
okini3939 0:d18dff347122 341 }
okini3939 0:d18dff347122 342
okini3939 0:d18dff347122 343 /*
okini3939 0:d18dff347122 344 * Store the message length as the last 8 octets
okini3939 0:d18dff347122 345 */
okini3939 0:d18dff347122 346 context->Message_Block[56] = context->Length_High >> 24;
okini3939 0:d18dff347122 347 context->Message_Block[57] = context->Length_High >> 16;
okini3939 0:d18dff347122 348 context->Message_Block[58] = context->Length_High >> 8;
okini3939 0:d18dff347122 349 context->Message_Block[59] = context->Length_High;
okini3939 0:d18dff347122 350 context->Message_Block[60] = context->Length_Low >> 24;
okini3939 0:d18dff347122 351 context->Message_Block[61] = context->Length_Low >> 16;
okini3939 0:d18dff347122 352 context->Message_Block[62] = context->Length_Low >> 8;
okini3939 0:d18dff347122 353 context->Message_Block[63] = context->Length_Low;
okini3939 0:d18dff347122 354
okini3939 0:d18dff347122 355 SHA1ProcessMessageBlock(context);
okini3939 0:d18dff347122 356 }
okini3939 0:d18dff347122 357
okini3939 0:d18dff347122 358 void sha1 (const char *input, int len, char *output) {
okini3939 0:d18dff347122 359 SHA1Context sha;
okini3939 0:d18dff347122 360
okini3939 0:d18dff347122 361 SHA1Reset(&sha);
okini3939 0:d18dff347122 362 SHA1Input(&sha, (unsigned char*)input, len);
okini3939 0:d18dff347122 363 SHA1Result(&sha, (uint8_t*)output);
okini3939 0:d18dff347122 364 }