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); }
int pgp_s2k_process(PGP_S2K *s2k, int cipher, const uint8 *key, int key_len) { int res; PX_MD *md; s2k->key_len = pgp_get_cipher_key_size(cipher); if (s2k->key_len <= 0) return PXE_PGP_UNSUPPORTED_CIPHER; res = pgp_load_digest(s2k->digest_algo, &md); if (res < 0) return res; switch (s2k->mode) { case 0: res = calc_s2k_simple(s2k, md, key, key_len); break; case 1: res = calc_s2k_salted(s2k, md, key, key_len); break; case 3: res = calc_s2k_iter_salted(s2k, md, key, key_len); break; default: res = PXE_PGP_BAD_S2K_MODE; } px_md_free(md); return res; }
int main (int argc, char** argv) { /* uint8 data[1024]; unsigned len = 18; for (int i=0;i<len;i++) { printf("%i\n",(int)data[i]); } return(0); } */ PX_MD *md; uint8 rnd[16]; char data[1024]; int i; strcpy(data,"This is a test"); if (px_get_random_bytes(rnd, 16) < 0) { printf("No random bytes\n"); exit(1); } if (px_find_digest("sha1", &md) < 0) { printf("No sha\n"); exit(1); } for (i=0;i<16;i++) { printf("%i ",rnd[i]); } printf("\n"); /* * Try to make the feeding unpredictable. * * Prefer data over keys, as it's rather likely that key is same in * several calls. */ if (data && rnd[0] >= 32) { add_block_entropy(md, data); } if (data && rnd[1] >= 160) { add_block_entropy(md, data); } if (data && rnd[2] >= 160) add_block_entropy(md, data); px_md_free(md); memset(rnd, 0, sizeof(rnd)); }
static void hmac_free(PX_HMAC *h) { unsigned bs; bs = px_md_block_size(h->md); px_md_free(h->md); memset(h->p.ipad, 0, bs); memset(h->p.opad, 0, bs); px_free(h->p.ipad); px_free(h->p.opad); px_free(h); }
static int check_key_sha1(PullFilter *src, PGP_PubKey *pk) { int res; uint8 got_sha1[20]; uint8 my_sha1[20]; PX_MD *md; res = pullf_read_fixed(src, 20, got_sha1); if (res < 0) return res; res = pgp_load_digest(PGP_DIGEST_SHA1, &md); if (res < 0) goto err; switch (pk->algo) { case PGP_PUB_ELG_ENCRYPT: pgp_mpi_hash(md, pk->sec.elg.x); break; case PGP_PUB_RSA_SIGN: case PGP_PUB_RSA_ENCRYPT: case PGP_PUB_RSA_ENCRYPT_SIGN: pgp_mpi_hash(md, pk->sec.rsa.d); pgp_mpi_hash(md, pk->sec.rsa.p); pgp_mpi_hash(md, pk->sec.rsa.q); pgp_mpi_hash(md, pk->sec.rsa.u); break; case PGP_PUB_DSA_SIGN: pgp_mpi_hash(md, pk->sec.dsa.x); break; } px_md_finish(md, my_sha1); px_md_free(md); if (memcmp(my_sha1, got_sha1, 20) != 0) { px_debug("key sha1 check failed"); res = PXE_PGP_KEYPKT_CORRUPT; } err: memset(got_sha1, 0, 20); memset(my_sha1, 0, 20); return res; }
/* * Mix user data into RNG. It is for user own interests to have * RNG state shuffled. */ static void add_entropy(text *data1, text *data2, text *data3) { PX_MD *md; uint8 rnd[3]; if (!data1 && !data2 && !data3) return; if (px_get_random_bytes(rnd, 3) < 0) return; if (px_find_digest("sha1", &md) < 0) return; /* * Try to make the feeding unpredictable. * * Prefer data over keys, as it's rather likely that key is same in * several calls. */ /* chance: 7/8 */ if (data1 && rnd[0] >= 32) add_block_entropy(md, data1); /* chance: 5/8 */ if (data2 && rnd[1] >= 160) add_block_entropy(md, data2); /* chance: 5/8 */ if (data3 && rnd[2] >= 160) add_block_entropy(md, data3); px_md_free(md); memset(rnd, 0, sizeof(rnd)); }
int px_find_hmac(const char *name, PX_HMAC **res) { int err; PX_MD *md; PX_HMAC *h; unsigned bs; err = px_find_digest(name, &md); if (err) return err; bs = px_md_block_size(md); if (bs < 2) { px_md_free(md); return PXE_HASH_UNUSABLE_FOR_HMAC; } h = px_alloc(sizeof(*h)); h->p.ipad = px_alloc(bs); h->p.opad = px_alloc(bs); h->md = md; h->result_size = hmac_result_size; h->block_size = hmac_block_size; h->reset = hmac_reset; h->update = hmac_update; h->finish = hmac_finish; h->free = hmac_free; h->init = hmac_init; *res = h; return 0; }
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; }