Datum pg_digest(PG_FUNCTION_ARGS) { bytea *arg; text *name; unsigned len, hlen; PX_MD *md; bytea *res; name = PG_GETARG_TEXT_P(1); /* will give error if fails */ md = find_provider(name, (PFN) px_find_digest, "Digest", 0); hlen = px_md_result_size(md); res = (text *) palloc(hlen + VARHDRSZ); SET_VARSIZE(res, hlen + VARHDRSZ); arg = PG_GETARG_BYTEA_P(0); len = VARSIZE(arg) - VARHDRSZ; px_md_update(md, (uint8 *) VARDATA(arg), len); px_md_finish(md, (uint8 *) VARDATA(res)); px_md_free(md); PG_FREE_IF_COPY(arg, 0); PG_FREE_IF_COPY(name, 1); PG_RETURN_BYTEA_P(res); }
static void hmac_init(PX_HMAC *h, const uint8 *key, unsigned klen) { unsigned bs, hlen, i; uint8 *keybuf; PX_MD *md = h->md; bs = px_md_block_size(md); hlen = px_md_result_size(md); keybuf = px_alloc(bs); memset(keybuf, 0, bs); if (klen > bs) { px_md_update(md, key, klen); px_md_finish(md, keybuf); px_md_reset(md); } else memcpy(keybuf, key, klen); for (i = 0; i < bs; i++) { h->p.ipad[i] = keybuf[i] ^ HMAC_IPAD; h->p.opad[i] = keybuf[i] ^ HMAC_OPAD; } memset(keybuf, 0, bs); px_free(keybuf); px_md_update(md, h->p.ipad, bs); }
static int calc_s2k_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len) { unsigned md_rlen; uint8 buf[PGP_MAX_DIGEST]; unsigned preload = 0; uint8 *dst; unsigned remain; md_rlen = px_md_result_size(md); dst = s2k->key; remain = s2k->key_len; while (remain > 0) { px_md_reset(md); if (preload > 0) { memset(buf, 0, preload); px_md_update(md, buf, preload); } preload++; px_md_update(md, s2k->salt, PGP_S2K_SALT); px_md_update(md, key, key_len); px_md_finish(md, buf); if (remain > md_rlen) { memcpy(dst, buf, md_rlen); remain -= md_rlen; dst += md_rlen; } else { memcpy(dst, buf, remain); remain = 0; } } px_memset(buf, 0, sizeof(buf)); return 0; }
static void hmac_finish(PX_HMAC *h, uint8 *dst) { PX_MD *md = h->md; unsigned bs, hlen; uint8 *buf; bs = px_md_block_size(md); hlen = px_md_result_size(md); buf = px_alloc(hlen); px_md_finish(md, buf); px_md_reset(md); px_md_update(md, h->p.opad, bs); px_md_update(md, buf, hlen); px_md_finish(md, dst); memset(buf, 0, hlen); px_free(buf); }
static unsigned hmac_result_size(PX_HMAC *h) { return px_md_result_size(h->md); }
static int calc_s2k_iter_salted(PGP_S2K *s2k, PX_MD *md, const uint8 *key, unsigned key_len) { unsigned md_rlen; uint8 buf[PGP_MAX_DIGEST]; uint8 *dst; unsigned preload = 0; unsigned remain, c, curcnt, count; count = s2k_decode_count(s2k->iter); md_rlen = px_md_result_size(md); remain = s2k->key_len; dst = s2k->key; while (remain > 0) { px_md_reset(md); if (preload) { memset(buf, 0, preload); px_md_update(md, buf, preload); } preload++; px_md_update(md, s2k->salt, PGP_S2K_SALT); px_md_update(md, key, key_len); curcnt = PGP_S2K_SALT + key_len; while (curcnt < count) { if (curcnt + PGP_S2K_SALT < count) c = PGP_S2K_SALT; else c = count - curcnt; px_md_update(md, s2k->salt, c); curcnt += c; if (curcnt + key_len < count) c = key_len; else if (curcnt < count) c = count - curcnt; else break; px_md_update(md, key, c); curcnt += c; } px_md_finish(md, buf); if (remain > md_rlen) { memcpy(dst, buf, md_rlen); remain -= md_rlen; dst += md_rlen; } else { memcpy(dst, buf, remain); remain = 0; } } px_memset(buf, 0, sizeof(buf)); return 0; }