int md5_memory(const void *mem, uint64_t len, uint8_t hash[16]) { uint8_t *buffer; uint64_t offs = 0; // uint32_t l=0; struct md_context context; // printf("hashing %ld bytes.\n", len); buffer = (uint8_t *)malloc(BUFSIZE); md5_start(&context); while(len > BUFSIZE) { memcpy(buffer, mem+offs, BUFSIZE); md5_update(&context, buffer, BUFSIZE); len -= BUFSIZE; offs += BUFSIZE; } memcpy(buffer, mem+offs, len); md5_update(&context, buffer, len); md5_finish(&context); memcpy(hash, context.digest, 16); return 0; }
int md5_file(const char *path, uint8_t hash[16]) { uint8_t *buffer; uint32_t l; FILE *fp; struct md_context context; buffer = (uint8_t *)malloc(BUFSIZE); if(!(fp = fopen(path, "rb"))) { fprintf(stderr, "File couldn't be read.\n"); fprintf(stderr, "%s\n", strerror(errno)); return -1; } md5_start(&context); l = fread(buffer, 1, BUFSIZE, fp); while(l == BUFSIZE) { md5_update(&context, buffer, BUFSIZE); l = fread(buffer, 1, BUFSIZE, fp); } md5_update(&context, buffer, l); md5_finish(&context); memcpy(hash, context.digest, 16); return 0; }
static void compute_cram_md5(uschar *secret, uschar *challenge, uschar *digestptr) { md5 base; int i; int len = Ustrlen(secret); uschar isecret[64]; uschar osecret[64]; uschar md5secret[16]; /* If the secret is longer than 64 characters, we compute its MD5 digest and use that. */ if (len > 64) { md5_start(&base); md5_end(&base, (uschar *)secret, len, md5secret); secret = (uschar *)md5secret; len = 16; } /* The key length is now known to be <= 64. Set up the padded and xor'ed versions. */ memcpy(isecret, secret, len); memset(isecret+len, 0, 64-len); memcpy(osecret, isecret, 64); for (i = 0; i < 64; i++) { isecret[i] ^= 0x36; osecret[i] ^= 0x5c; } /* Compute the inner MD5 digest */ md5_start(&base); md5_mid(&base, isecret); md5_end(&base, (uschar *)challenge, Ustrlen(challenge), md5secret); /* Compute the outer MD5 digest */ md5_start(&base); md5_mid(&base, osecret); md5_end(&base, md5secret, 16, digestptr); }