diff options
Diffstat (limited to 'src/pluto/ipsec_doi.c')
-rw-r--r-- | src/pluto/ipsec_doi.c | 81 |
1 files changed, 24 insertions, 57 deletions
diff --git a/src/pluto/ipsec_doi.c b/src/pluto/ipsec_doi.c index 57c262487..38fe1dd52 100644 --- a/src/pluto/ipsec_doi.c +++ b/src/pluto/ipsec_doi.c @@ -122,37 +122,11 @@ echo_hdr(struct msg_digest *md, bool enc, u_int8_t np) * We make the leap that the length should be that of the group * (see quoted passage at start of ACCEPT_KE). */ -static void compute_dh_shared(struct state *st, const chunk_t g, - const struct oakley_group_desc *group) +static void compute_dh_shared(struct state *st, const chunk_t g) { - MP_INT mp_g, mp_shared; - struct timeval tv0, tv1; - unsigned long tv_diff; - - gettimeofday(&tv0, NULL); - passert(st->st_sec_in_use); - n_to_mpz(&mp_g, g.ptr, g.len); - mpz_init(&mp_shared); - mpz_powm(&mp_shared, &mp_g, &st->st_sec, group->modulus); - mpz_clear(&mp_g); - free(st->st_shared.ptr); /* happens in odd error cases */ - st->st_shared = mpz_to_n(&mp_shared, group->bytes); - mpz_clear(&mp_shared); - gettimeofday(&tv1, NULL); - tv_diff=(tv1.tv_sec - tv0.tv_sec) * 1000000 + (tv1.tv_usec - tv0.tv_usec); - DBG(DBG_CRYPT, - DBG_log("compute_dh_shared(): time elapsed (%s): %ld usec" - , enum_show(&oakley_group_names, st->st_oakley.group->group) - , tv_diff); - ); - /* if took more than 200 msec ... */ - if (tv_diff > 200000) { - loglog(RC_LOG_SERIOUS, "WARNING: compute_dh_shared(): for %s took " - "%ld usec" - , enum_show(&oakley_group_names, st->st_oakley.group->group) - , tv_diff); - } - + passert(st->st_dh); + st->st_dh->set_other_public_value(st->st_dh, g); + st->st_dh->get_shared_secret(st->st_dh, &st->st_shared); DBG_cond_dump_chunk(DBG_CRYPT, "DH shared secret:\n", st->st_shared); } @@ -160,30 +134,23 @@ static void compute_dh_shared(struct state *st, const chunk_t g, * the corresponding public value (g). This is emitted as a KE payload. */ static bool build_and_ship_KE(struct state *st, chunk_t *g, - const struct oakley_group_desc *group, + const struct dh_desc *group, pb_stream *outs, u_int8_t np) { - if (!st->st_sec_in_use) + if (st->st_dh == NULL) { - u_char tmp[LOCALSECRETSIZE]; - MP_INT mp_g; - rng_t *rng; - - rng = lib->crypto->create_rng(lib->crypto, RNG_STRONG); - rng->get_bytes(rng, LOCALSECRETSIZE, tmp); - rng->destroy(rng); - st->st_sec_in_use = TRUE; - n_to_mpz(&st->st_sec, tmp, LOCALSECRETSIZE); - - mpz_init(&mp_g); - mpz_powm(&mp_g, &groupgenerator, &st->st_sec, group->modulus); - free(g->ptr); /* happens in odd error cases */ - *g = mpz_to_n(&mp_g, group->bytes); - mpz_clear(&mp_g); - DBG(DBG_CRYPT, - DBG_dump("Local DH secret:\n", tmp, LOCALSECRETSIZE); - DBG_dump_chunk("Public DH value sent:\n", *g)); + st->st_dh = lib->crypto->create_dh(lib->crypto, group->algo_id); + if (st->st_dh == NULL) + { + plog("Diffie Hellman group %N is not available", + diffie_hellman_group_names, group->algo_id); + return FALSE; + } } + st->st_dh->get_my_public_value(st->st_dh, g); + DBG(DBG_CRYPT, + DBG_dump_chunk("Public DH value sent:\n", *g) + ) return out_generic_chunk(np, &isakmp_keyex_desc, outs, *g, "keyex value"); } @@ -197,13 +164,13 @@ static bool build_and_ship_KE(struct state *st, chunk_t *g, * value with zeros. */ static notification_t accept_KE(chunk_t *dest, const char *val_name, - const struct oakley_group_desc *gr, + const struct dh_desc *gr, pb_stream *pbs) { - if (pbs_left(pbs) != gr->bytes) + if (pbs_left(pbs) != gr->modulus_size) { loglog(RC_LOG_SERIOUS, "KE has %u byte DH public value; %u required" - , (unsigned) pbs_left(pbs), (unsigned) gr->bytes); + , (unsigned) pbs_left(pbs), gr->modulus_size); /* XXX Could send notification back */ return INVALID_KEY_INFORMATION; } @@ -3473,7 +3440,7 @@ stf_status main_inI2_outR2(struct msg_digest *md) /* next message will be encrypted, but not this one. * We could defer this calculation. */ - compute_dh_shared(st, st->st_gi, st->st_oakley.group); + compute_dh_shared(st, st->st_gi); if (!generate_skeyids_iv(st)) return STF_FAIL + AUTHENTICATION_FAILED; update_iv(st); @@ -3535,7 +3502,7 @@ stf_status main_inR2_outI3(struct msg_digest *md) send_cr = !no_cr_send && send_cert && !has_preloaded_public_key(st); /* done parsing; initialize crypto */ - compute_dh_shared(st, st->st_gr, st->st_oakley.group); + compute_dh_shared(st, st->st_gr); if (!generate_skeyids_iv(st)) return STF_FAIL + AUTHENTICATION_FAILED; @@ -4946,7 +4913,7 @@ static stf_status quick_inI1_outR1_tail(struct verify_oppo_bundle *b, return STF_INTERNAL_ERROR; /* MPZ-Operations might be done after sending the packet... */ - compute_dh_shared(st, st->st_gi, st->st_pfs_group); + compute_dh_shared(st, st->st_gi); } /* [ IDci, IDcr ] out */ @@ -5061,7 +5028,7 @@ stf_status quick_inR1_outI2(struct msg_digest *md) RETURN_STF_FAILURE(accept_PFS_KE(md, &st->st_gr, "Gr", "Quick Mode R1")); if (st->st_pfs_group != NULL) - compute_dh_shared(st, st->st_gr, st->st_pfs_group); + compute_dh_shared(st, st->st_gr); /* [ IDci, IDcr ] in; these must match what we sent */ |