X-Git-Url: https://git.distorted.org.uk/~mdw/secnet/blobdiff_plain/bd98cd6bd47584447fcbf84f72ee9388f36ebb8c..5c21ea51197108524fae54c3fdd6c8048816c08c:/site.c diff --git a/site.c b/site.c index db65bd8..8fa4c11 100644 --- a/site.c +++ b/site.c @@ -288,6 +288,7 @@ struct site { uint64_t timeout; /* Timeout for current state */ uint8_t *dhsecret; uint8_t *sharedsecret; + uint32_t sharedsecretlen; struct transform_inst_if *new_transform; /* For key setup/verify */ }; @@ -463,7 +464,7 @@ static bool_t check_msg(struct site *st, uint32_t type, struct msg *m, return False; } if (type==LABEL_MSG2) return True; - if (memcmp(m->nR,st->remoteN,NONCELEN)!=0) { + if (!consttime_memeq(m->nR,st->remoteN,NONCELEN)!=0) { *error="wrong remotely-generated nonce"; return False; } @@ -561,11 +562,11 @@ static bool_t process_msg3(struct site *st, struct buffer_if *msg3, /* Generate the shared key */ st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->len,m.pk, - st->sharedsecret,st->transform->keylen); + st->sharedsecret,st->sharedsecretlen); /* Set up the transform */ st->new_transform->setkey(st->new_transform->st,st->sharedsecret, - st->transform->keylen); + st->sharedsecretlen,st->setup_priority); return True; } @@ -609,10 +610,10 @@ static bool_t process_msg4(struct site *st, struct buffer_if *msg4, m.pk[m.pklen]=0; /* Generate the shared key */ st->dh->makeshared(st->dh->st,st->dhsecret,st->dh->len,m.pk, - st->sharedsecret,st->transform->keylen); + st->sharedsecret,st->sharedsecretlen); /* Set up the transform */ st->new_transform->setkey(st->new_transform->st,st->sharedsecret, - st->transform->keylen); + st->sharedsecretlen,st->setup_priority); return True; } @@ -730,7 +731,8 @@ static bool_t process_msg6(struct site *st, struct buffer_if *msg6, return True; } -static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0) +static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0, + const struct comm_addr *src) { cstring_t transform_err, auxkey_err, newkey_err="n/a"; struct msg0 m; @@ -749,11 +751,8 @@ static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0) "peer has used new key","auxiliary key",LOG_SEC); return True; } - - if (problem==2) { - slog(st,LOG_DROP,"transform: %s (merely skew)",transform_err); - return False; - } + if (problem==2) + goto skew; buffer_copy(msg0, &st->scratch); problem = st->auxiliary_key.transform->reverse @@ -777,11 +776,14 @@ static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0) } return True; } + if (problem==2) + goto skew; if (st->state==SITE_SENTMSG5) { buffer_copy(msg0, &st->scratch); - if (!st->new_transform->reverse(st->new_transform->st, - msg0,&newkey_err)) { + problem = st->new_transform->reverse(st->new_transform->st, + msg0,&newkey_err); + if (!problem) { /* It looks like we didn't get the peer's MSG6 */ /* This is like a cut-down enter_new_state(SITE_RUN) */ slog(st,LOG_STATE,"will enter state RUN (MSG0 with new key)"); @@ -790,11 +792,18 @@ static bool_t decrypt_msg0(struct site *st, struct buffer_if *msg0) activate_new_key(st); return True; /* do process the data in this packet */ } + if (problem==2) + goto skew; } slog(st,LOG_SEC,"transform: %s (aux: %s, new: %s)", transform_err,auxkey_err,newkey_err); initiate_key_setup(st,"incoming message would not decrypt"); + send_nak(src,m.dest,m.source,m.type,msg0,"message would not decrypt"); + return False; + + skew: + slog(st,LOG_DROP,"transform: %s (merely skew)",transform_err); return False; } @@ -803,7 +812,7 @@ static bool_t process_msg0(struct site *st, struct buffer_if *msg0, { uint32_t type; - if (!decrypt_msg0(st,msg0)) + if (!decrypt_msg0(st,msg0,src)) return False; CHECK_AVAIL(msg0,4); @@ -1009,7 +1018,7 @@ static void enter_state_run(struct site *st) memset(st->remoteN,0,NONCELEN); st->new_transform->delkey(st->new_transform->st); memset(st->dhsecret,0,st->dh->len); - memset(st->sharedsecret,0,st->transform->keylen); + memset(st->sharedsecret,0,st->sharedsecretlen); set_link_quality(st); } @@ -1285,7 +1294,7 @@ static bool_t site_incoming(void *sst, struct buffer_if *buf, uint32_t msgtype=ntohl(get_uint32(buf->start+8)); if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True); switch (msgtype) { - case 0: /* NAK */ + case LABEL_NAK: /* If the source is our current peer then initiate a key setup, because our peer's forgotten the key */ if (get_uint32(buf->start+4)==st->current.remote_session_id) { @@ -1557,7 +1566,8 @@ static list_t *site_apply(closure_t *self, struct cloc loc, dict_t *context, transport_peers_clear(st,&st->setup_peers); /* XXX mlock these */ st->dhsecret=safe_malloc(st->dh->len,"site:dhsecret"); - st->sharedsecret=safe_malloc(st->transform->keylen,"site:sharedsecret"); + st->sharedsecretlen=st->transform->keylen?:st->dh->ceil_len; + st->sharedsecret=safe_malloc(st->sharedsecretlen,"site:sharedsecret"); /* We need to compute some properties of our comms */ #define COMPUTE_WORST(pad) \