| 229 | /* Add padding and return the message digest. */ |
| 230 | |
| 231 | void SHA1Final( |
| 232 | unsigned char digest[20], |
| 233 | SHA1_CTX * context |
| 234 | ) |
| 235 | { |
| 236 | unsigned i; |
| 237 | |
| 238 | unsigned char finalcount[8]; |
| 239 | |
| 240 | unsigned char c; |
| 241 | |
| 242 | #if 0 /* untested "improvement" by DHR */ |
| 243 | /* Convert context->count to a sequence of bytes |
| 244 | * in finalcount. Second element first, but |
| 245 | * big-endian order within element. |
| 246 | * But we do it all backwards. |
| 247 | */ |
| 248 | unsigned char *fcp = &finalcount[8]; |
| 249 | |
| 250 | for (i = 0; i < 2; i++) |
| 251 | { |
| 252 | uint32_t t = context->count[i]; |
| 253 | |
| 254 | int j; |
| 255 | |
| 256 | for (j = 0; j < 4; t >>= 8, j++) |
| 257 | *--fcp = (unsigned char) t} |
| 258 | #else |
| 259 | for (i = 0; i < 8; i++) |
| 260 | { |
| 261 | finalcount[i] = (unsigned char) ((context->count[(i >= 4 ? 0 : 1)] >> ((3 - (i & 3)) * 8)) & 255); /* Endian independent */ |
| 262 | } |
| 263 | #endif |
| 264 | c = 0200; |
| 265 | SHA1Update(context, &c, 1); |
| 266 | while ((context->count[0] & 504) != 448) |
| 267 | { |
| 268 | c = 0000; |
| 269 | SHA1Update(context, &c, 1); |
| 270 | } |
| 271 | SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ |
| 272 | for (i = 0; i < 20; i++) |
| 273 | { |
| 274 | digest[i] = (unsigned char) |
| 275 | ((context->state[i >> 2] >> ((3 - (i & 3)) * 8)) & 255); |
| 276 | } |
| 277 | /* Wipe variables */ |
| 278 | memset(context, '\0', sizeof(*context)); |
| 279 | memset(&finalcount, '\0', sizeof(finalcount)); |
| 280 | } |
| 281 | |
| 282 | void SHA1( |
| 283 | char *hash_out, |
no test coverage detected