/* MUST BE THREAD-SAFE */ void calc_dh(struct pluto_crypto_req *r) { /* copy the request, since the reply will re-use the memory of the r->pcr_d.dhq */ struct pcr_skeyid_q dhq; memcpy(&dhq, &r->pcr_d.dhq, sizeof(r->pcr_d.dhq)); /* clear out the reply */ struct pcr_skeyid_r *skr = &r->pcr_d.dhr; zero(skr); /* ??? pointer fields might not be NULLed */ INIT_WIRE_ARENA(*skr); const struct oakley_group_desc *group = lookup_group(dhq.oakley_group); passert(group != NULL); SECKEYPrivateKey *ltsecret = dhq.secret; SECKEYPublicKey *pubk = dhq.pubk; /* now calculate the (g^x)(g^y) */ chunk_t g; setchunk_from_wire(g, &dhq, dhq.role == ORIGINAL_RESPONDER ? &dhq.gi : &dhq.gr); DBG(DBG_CRYPT, DBG_dump_chunk("peer's g: ", g)); const char *story; /* we ignore the value */ skr->shared = calc_dh_shared(g, ltsecret, group, pubk, &story); }
void pcr_dh_init(struct pluto_crypto_req *r, enum pluto_crypto_requests pcr_type, enum crypto_importance pcr_pcim) { pcr_init(r, pcr_type, pcr_pcim); INIT_WIRE_ARENA(r->pcr_d.dhq); }
/* MUST BE THREAD-SAFE */ void calc_dh_v2(struct pluto_crypto_req *r, const char **story) { struct pcr_skeycalc_v2_r *const skr = &r->pcr_d.dhv2; /* copy the request, since the reply will re-use the memory of the r->pcr_d.dhq */ struct pcr_skeyid_q dhq; memcpy(&dhq, &r->pcr_d.dhq, sizeof(r->pcr_d.dhq)); /* clear out the reply (including pointers) */ static const struct pcr_skeycalc_v2_r zero_pcr_skeycalc_v2_r; *skr = zero_pcr_skeycalc_v2_r; INIT_WIRE_ARENA(*skr); const struct oakley_group_desc *group = lookup_group(dhq.oakley_group); passert(group != NULL); SECKEYPrivateKey *ltsecret = dhq.secret; SECKEYPublicKey *pubk = dhq.pubk; /* now calculate the (g^x)(g^y) --- need gi on responder, gr on initiator */ chunk_t g; setchunk_from_wire(g, &dhq, dhq.role == ORIGINAL_RESPONDER ? &dhq.gi : &dhq.gr); DBG(DBG_CRYPT, DBG_dump_chunk("peer's g: ", g)); skr->shared = calc_dh_shared(g, ltsecret, group, pubk, story); if (skr->shared != NULL) { /* okay, so now all the shared key material */ calc_skeyseed_v2(&dhq, /* input */ skr->shared, /* input */ dhq.key_size, /* input */ dhq.salt_size, /* input */ &skr->skeyseed, /* output */ &skr->skeyid_d, /* output */ &skr->skeyid_ai, /* output */ &skr->skeyid_ar, /* output */ &skr->skeyid_ei, /* output */ &skr->skeyid_er, /* output */ &skr->skeyid_pi, /* output */ &skr->skeyid_pr, /* output */ &skr->skey_initiator_salt, /* output */ &skr->skey_responder_salt, /* output */ &skr->skey_chunk_SK_pi, /* output */ &skr->skey_chunk_SK_pr); /* output */ } }
int main(int argc, char *argv[]) { struct pluto_crypto_req r; struct pcr_skeycalc_v2_r *skr = &r.pcr_d.dhv2; struct pcr_skeyid_q *skq = &r.pcr_d.dhq; progname = argv[0]; cur_debugging = DBG_CRYPT; /* initialize list of moduli */ init_crypto(); INIT_WIRE_ARENA(*skq); skq->auth = tc2_auth; skq->prf_hash = tc2_hash; skq->integ_hash = tc2_hash; skq->oakley_group = tc2_oakleygroup; skq->init = tc2_init; skq->keysize = tc2_encrypter->keydeflen / BITS_PER_BYTE; #define copydatlen(field, data, len) { \ chunk_t tchunk; \ setchunk(tchunk, data, len); \ WIRE_CLONE_CHUNK(*skq, field, tchunk); \ } copydatlen(ni, tc2_ni, tc2_ni_len); copydatlen(nr, tc2_nr, tc2_nr_len); copydatlen(gi, tc2_gi, tc2_gi_len); copydatlen(gr, tc2_gr, tc2_gr_len); copydatlen(secret, tc2_secret, tc2_secret_len); copydatlen(icookie, tc2_icookie, tc2_icookie_len); copydatlen(rcookie, tc2_rcookie, tc2_rcookie_len); #define dumpdat(field) \ libreswan_DBG_dump(#field, \ WIRE_CHUNK_PTR(*skq, field), \ skq->field.len); dumpdat(icookie); dumpdat(rcookie); dumpdat(ni); dumpdat(nr); dumpdat(gi); dumpdat(gr); dumpdat(secret); fflush(stdout); fflush(stderr); calc_dh_v2(&r); printf("\noutput:\n"); fflush(stdout); fflush(stderr); #define dumpskr(FOO) { void *FOO = WIRE_CHUNK_PTR(*skr, FOO); \ libreswan_DBG_dump(#FOO, FOO, skr->FOO.len); \ } dumpskr(shared); dumpskr(skeyseed); dumpskr(skeyid_d); dumpskr(skeyid_ai); dumpskr(skeyid_ar); dumpskr(skeyid_ei); dumpskr(skeyid_er); dumpskr(skeyid_pi); dumpskr(skeyid_pr); exit(0); }
int main(int argc, char *argv[]) { struct pluto_crypto_req r; struct pcr_skeyid_r *skr = &r.pcr_d.dhr; struct pcr_skeyid_q *skq = &r.pcr_d.dhq; progname = argv[0]; /* initialize list of moduli */ init_crypto(); INIT_WIRE_ARENA(*skq); skq->auth = tc2_auth; skq->prf_hash = tc2_hash; skq->oakley_group = tc2_oakleygroup; skq->init = tc2_init; skq->keysize = tc2_encrypter->keydeflen / BITS_PER_BYTE; #define copydatlen(field, data, len) { \ chunk_t tchunk; \ setchunk(tchunk, data, len); \ WIRE_CLONE_CHUNK(*skq, field, tchunk); \ } copydatlen(ni, tc2_ni, tc2_ni_len); copydatlen(nr, tc2_nr, tc2_nr_len); copydatlen(gi, tc2_gi, tc2_gi_len); copydatlen(gr, tc2_gr, tc2_gr_len); copydatlen(secret, tc2_secret, tc2_secret_len); copydatlen(icookie, tc2_icookie, tc2_icookie_len); copydatlen(rcookie, tc2_rcookie, tc2_rcookie_len); #define dumpdat(field) \ libreswan_DBG_dump(#field, \ WIRE_CHUNK_PTR(*skq, field), \ skq->field.len); dumpdat(icookie); dumpdat(rcookie); dumpdat(ni); dumpdat(nr); dumpdat(gi); dumpdat(gr); dumpdat(secret); fflush(stdout); fflush(stderr); calc_dh_iv(&r); /* ??? NSS may fail */ printf("\noutput:\n"); { void *shared = WIRE_CHUNK_PTR(*skr, shared); libreswan_DBG_dump("shared", shared, skr->shared.len); } exit(4); }