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.
*
* %$r_A = g^{\rho_A}$% Alice's challenge
* %$c_A = H(\cookie{cookie}, r_A)$% Alice's cookie
*
* %$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}$%
* 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}$%
G_EXP(gg, r, c, kpriv);
h = GH_INIT(algs.h);
HASH_STRING(h, "tripe-expected-reply");
G_EXP(gg, r, c, kpriv);
h = GH_INIT(algs.h);
HASH_STRING(h, "tripe-expected-reply");
hashge(h, c);
hashge(h, kx->c);
hashge(h, r);
hashge(h, c);
hashge(h, kx->c);
hashge(h, r);
trace(T_CRYPTO, "crypto: recovered log = %s", mpstr(a));
}))
GH_DESTROY(h);
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, {
if (!ok) {
a_warn("KX", "?PEER", kx->p, "bad-expected-reply-log", A_END);
IF_TRACING(T_KEYEXCH, IF_TRACING(T_CRYPTO, {
h = GH_INIT(algs.h);
HASH_STRING(h, "tripe-expected-reply");
h = GH_INIT(algs.h);
HASH_STRING(h, "tripe-expected-reply");
hashge(h, kx->c);
hashge(h, kxc->c);
hashge(h, kx->rx);
hashge(h, kx->c);
hashge(h, kxc->c);
hashge(h, kx->rx);
algswitch algs;
/*----- Static variables --------------------------------------------------*/
algswitch algs;
/*----- Static variables --------------------------------------------------*/
if (kpriv)
mp_drop(kpriv);
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, {
/* --- Dump out the group --- */
IF_TRACING(T_KEYMGMT, {
extern sel_state sel; /* Global I/O event state */
extern group *gg; /* The group we work in */
extern mp *kpriv; /* Our private key */
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 */
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 */