| 195 | } |
| 196 | |
| 197 | void MD5_Final(unsigned char *result, MD5_CTX *ctx) { |
| 198 | unsigned long used, free; |
| 199 | used = ctx->lo & 0x3f; |
| 200 | ctx->buffer[used++] = 0x80; |
| 201 | free = 64 - used; |
| 202 | |
| 203 | if (free < 8) { |
| 204 | memset(&ctx->buffer[used], 0, free); |
| 205 | body(ctx, ctx->buffer, 64); |
| 206 | used = 0; |
| 207 | free = 64; |
| 208 | } |
| 209 | |
| 210 | memset(&ctx->buffer[used], 0, free - 8); |
| 211 | |
| 212 | ctx->lo <<= 3; |
| 213 | ctx->buffer[56] = ctx->lo; |
| 214 | ctx->buffer[57] = ctx->lo >> 8; |
| 215 | ctx->buffer[58] = ctx->lo >> 16; |
| 216 | ctx->buffer[59] = ctx->lo >> 24; |
| 217 | ctx->buffer[60] = ctx->hi; |
| 218 | ctx->buffer[61] = ctx->hi >> 8; |
| 219 | ctx->buffer[62] = ctx->hi >> 16; |
| 220 | ctx->buffer[63] = ctx->hi >> 24; |
| 221 | body(ctx, ctx->buffer, 64); |
| 222 | result[0] = ctx->a; |
| 223 | result[1] = ctx->a >> 8; |
| 224 | result[2] = ctx->a >> 16; |
| 225 | result[3] = ctx->a >> 24; |
| 226 | result[4] = ctx->b; |
| 227 | result[5] = ctx->b >> 8; |
| 228 | result[6] = ctx->b >> 16; |
| 229 | result[7] = ctx->b >> 24; |
| 230 | result[8] = ctx->c; |
| 231 | result[9] = ctx->c >> 8; |
| 232 | result[10] = ctx->c >> 16; |
| 233 | result[11] = ctx->c >> 24; |
| 234 | result[12] = ctx->d; |
| 235 | result[13] = ctx->d >> 8; |
| 236 | result[14] = ctx->d >> 16; |
| 237 | result[15] = ctx->d >> 24; |
| 238 | memset(ctx, 0, sizeof(*ctx)); |
| 239 | } |
| 240 | } // namespace |
| 241 | |
| 242 | namespace mdf { |
no test coverage detected