static void gsicc_get_buff_hash(unsigned char *data, int64_t *hash, unsigned int num_bytes) { gs_md5_state_t md5; byte digest[16]; int k; int64_t word1,word2,shift; /* We could probably do something faster than this. But use this for now. */ gs_md5_init(&md5); gs_md5_append(&md5, data, num_bytes); gs_md5_finish(&md5, digest); /* For now, xor this into 64 bit word */ word1 = 0; word2 = 0; shift = 0; /* need to do it this way because of potential word boundary issues */ for( k = 0; k<8; k++) { word1 += ((int64_t) digest[k]) << shift; word2 += ((int64_t) digest[k+8]) << shift; shift += 8; } *hash = word1 ^ word2; }
/* compute and set a cache key's hash */ static void gp_cache_hash(gp_cache_entry *entry) { gs_md5_state_t md5; /* we use md5 hashes of the key */ gs_md5_init(&md5); gs_md5_append(&md5, entry->key, entry->keylen); gs_md5_finish(&md5, entry->hash); }
/* Get a digest. Apply 'flush' before calling. */ int s_MD5C_get_digest(stream *s, byte *buf, int buf_length) { stream_MD5E_state *const ss = (stream_MD5E_state *)s->state; gs_md5_state_t md5; byte b[16], *p; int l = min(16, buf_length), k; if (s->procs.process != s_MD5C_process) return 0; /* Must not happen. */ md5 = ss->md5; gs_md5_finish(&md5, b); memcpy(buf, b, l); for (p = b + l; p < b + sizeof(b); p += l) { for (k = 0; k < l && p + k < b + sizeof(b); k++) buf[k] ^= p[k]; } return l; }
/* Process a buffer. */ static int s_MD5E_process(stream_state * st, stream_cursor_read * pr, stream_cursor_write * pw, bool last) { stream_MD5E_state *const ss = (stream_MD5E_state *) st; int status = 0; if (pr->ptr < pr->limit) { gs_md5_append(&ss->md5, pr->ptr + 1, pr->limit - pr->ptr); pr->ptr = pr->limit; } if (last) { if (pw->limit - pw->ptr >= 16) { gs_md5_finish(&ss->md5, pw->ptr + 1); pw->ptr += 16; status = EOFC; } else status = 1; } return status; }