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); }
int pgp_mpi_hash(PX_MD * md, PGP_MPI * n) { uint8 buf[2]; buf[0] = n->bits >> 8; buf[1] = n->bits & 0xFF; px_md_update(md, buf, 2); px_md_update(md, n->data, n->bytes); return 0; }
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_reset(PX_HMAC *h) { PX_MD *md = h->md; unsigned bs = px_md_block_size(md); px_md_reset(md); 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 add_block_entropy(PX_MD *md, char *data) { uint8 sha1[20]; px_md_reset(md); px_md_update(md, (uint8 *) data, sizeof(data)); px_md_finish(md, sha1); px_add_entropy(sha1, 20); memset(sha1, 0, 20); }
/* * Mix a block of data into RNG. */ static void add_block_entropy(PX_MD *md, text *data) { uint8 sha1[20]; px_md_reset(md); px_md_update(md, (uint8 *) VARDATA(data), VARSIZE(data) - VARHDRSZ); px_md_finish(md, sha1); px_add_entropy(sha1, 20); memset(sha1, 0, 20); }
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 int calc_key_id(PGP_PubKey *pk) { int res; PX_MD *md; int len; uint8 hdr[3]; uint8 hash[20]; res = pgp_load_digest(PGP_DIGEST_SHA1, &md); if (res < 0) return res; len = 1 + 4 + 1; switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: len += 2 + pk->pub.elg.p->bytes; len += 2 + pk->pub.elg.g->bytes; len += 2 + pk->pub.elg.y->bytes; break; case PGP_PUB_RSA_SIGN: case PGP_PUB_RSA_ENCRYPT: case PGP_PUB_RSA_ENCRYPT_SIGN: len += 2 + pk->pub.rsa.n->bytes; len += 2 + pk->pub.rsa.e->bytes; break; case PGP_PUB_DSA_SIGN: len += 2 + pk->pub.dsa.p->bytes; len += 2 + pk->pub.dsa.q->bytes; len += 2 + pk->pub.dsa.g->bytes; len += 2 + pk->pub.dsa.y->bytes; break; } hdr[0] = 0x99; hdr[1] = len >> 8; hdr[2] = len & 0xFF; px_md_update(md, hdr, 3); px_md_update(md, &pk->ver, 1); px_md_update(md, pk->time, 4); px_md_update(md, &pk->algo, 1); switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: pgp_mpi_hash(md, pk->pub.elg.p); pgp_mpi_hash(md, pk->pub.elg.g); pgp_mpi_hash(md, pk->pub.elg.y); break; case PGP_PUB_RSA_SIGN: case PGP_PUB_RSA_ENCRYPT: case PGP_PUB_RSA_ENCRYPT_SIGN: pgp_mpi_hash(md, pk->pub.rsa.n); pgp_mpi_hash(md, pk->pub.rsa.e); break; case PGP_PUB_DSA_SIGN: pgp_mpi_hash(md, pk->pub.dsa.p); pgp_mpi_hash(md, pk->pub.dsa.q); pgp_mpi_hash(md, pk->pub.dsa.g); pgp_mpi_hash(md, pk->pub.dsa.y); break; } px_md_finish(md, hash); px_md_free(md); memcpy(pk->key_id, hash + 12, 8); memset(hash, 0, 20); return 0; }
static void hmac_update(PX_HMAC *h, const uint8 *data, unsigned dlen) { px_md_update(h->md, data, dlen); }
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; }