From 9317aa9290393480e8004bd443c38b5faa5f6f0c Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Fri, 27 Oct 2006 17:55:27 +0100 Subject: [PATCH] keyexch, keymgmt: Include the peer's public key in the check hash. This turns out to be necessary for security: otherwise an adversary can cross over two sessions, which is probably undesirable. This also requires that we know our own public key, which was previously unnecessary. Except for session-ids (we don't care if two `sessions' with the same peer get crossed over, because we don't distinguish them anyway), the protocol now matches the one described and proved secure in the crypto paper. --- keyexch.c | 12 +++++++++--- keymgmt.c | 6 ++++++ tripe.h | 1 + 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/keyexch.c b/keyexch.c index 80e0132a..f6786e09 100644 --- a/keyexch.c +++ b/keyexch.c @@ -47,7 +47,7 @@ * * %$r_A = g^{\rho_A}$% Alice's challenge * %$c_A = H(\cookie{cookie}, r_A)$% Alice's cookie - * %$v_A = \rho_A \xor H(\cookie{expected-reply}, r_A, r_B, b^{\rho_A})$% + * %$v_A = \rho_A \xor H(\cookie{expected-reply}, a, r_A, r_B, b^{\rho_A})$% * Alice's challenge check value * %$r_B^\alpha = a^{\rho_B}$% Alice's reply * %$K = r_B^{\rho_A} = r_B^{\rho_A} = g^{\rho_A\rho_B}$% @@ -415,6 +415,7 @@ static ge *getreply(keyexch *kx, ge *c, mp *ck) G_EXP(gg, r, c, kpriv); h = GH_INIT(algs.h); HASH_STRING(h, "tripe-expected-reply"); + hashge(h, kx->kpub); hashge(h, c); hashge(h, kx->c); hashge(h, r); @@ -427,8 +428,12 @@ static ge *getreply(keyexch *kx, ge *c, mp *ck) trace(T_CRYPTO, "crypto: recovered log = %s", mpstr(a)); })) GH_DESTROY(h); - G_EXP(gg, y, gg->g, a); - ok = G_EQ(gg, y, c); + if (MP_CMP(a, >=, gg->r)) + ok = 0; + else{ + G_EXP(gg, y, gg->g, a); + ok = G_EQ(gg, y, c); + } if (!ok) { a_warn("KX", "?PEER", kx->p, "bad-expected-reply-log", A_END); IF_TRACING(T_KEYEXCH, IF_TRACING(T_CRYPTO, { @@ -553,6 +558,7 @@ static int dochallenge(keyexch *kx, unsigned msg, buf *b) h = GH_INIT(algs.h); HASH_STRING(h, "tripe-expected-reply"); + hashge(h, kpub); hashge(h, kx->c); hashge(h, kxc->c); hashge(h, kx->rx); diff --git a/keymgmt.c b/keymgmt.c index 7163ddda..f645d156 100644 --- a/keymgmt.c +++ b/keymgmt.c @@ -34,6 +34,7 @@ group *gg; mp *kpriv; +ge *kpub; algswitch algs; /*----- Static variables --------------------------------------------------*/ @@ -398,6 +399,11 @@ tymatch:; if (kpriv) mp_drop(kpriv); + if (kpub) + G_DESTROY(g, kpub); + kpub = G_CREATE(g); + G_EXP(g, kpub, g->g, x); + /* --- Dump out the group --- */ IF_TRACING(T_KEYMGMT, { diff --git a/tripe.h b/tripe.h index 25255f32..5f62f16d 100644 --- a/tripe.h +++ b/tripe.h @@ -426,6 +426,7 @@ typedef struct admin { extern sel_state sel; /* Global I/O event state */ extern group *gg; /* The group we work in */ extern mp *kpriv; /* Our private key */ +extern ge *kpub; /* Our public key */ extern octet buf_i[PKBUFSZ], buf_o[PKBUFSZ], buf_t[PKBUFSZ]; extern const tunnel_ops *tunnels[]; /* Table of tunnels (0-term) */ extern const tunnel_ops *tun_default; /* Default tunnel to use */ -- 2.11.0