};
static int32_t wait_timeout(struct site *st) {
- return st->wait_timeout_mean;
+ int32_t t = st->wait_timeout_mean;
+ int8_t factor;
+ if (t < INT_MAX/2) {
+ st->random->generate(st->random->st,sizeof(factor),&factor);
+ t += (t / 256) * factor;
+ }
+ return t;
}
static _Bool set_new_transform(struct site *st, char *pk)
slog(st,LOG_SETUP_INIT,"key exchange negotiated transform"
" %d (capabilities ours=%#"PRIx32" theirs=%#"PRIx32")",
- st->chosen_transform->capab_transformnum,
+ st->chosen_transform->capab_bit,
st->local_capabilities, st->remote_capabilities);
return True;
}
if (hacky_par_mid_failnow()) return False;
if (type==LABEL_MSG3BIS)
- buf_append_uint8(&st->buffer,st->chosen_transform->capab_transformnum);
+ buf_append_uint8(&st->buffer,st->chosen_transform->capab_bit);
dhpub=st->dh->makepublic(st->dh->st,st->dhsecret,st->dh->len);
buf_append_string(&st->buffer,dhpub);
CHECK_AVAIL(msg,1);
m->capab_transformnum = buf_unprepend_uint8(msg);
} else {
- m->capab_transformnum = CAPAB_TRANSFORMNUM_ANCIENT;
+ m->capab_transformnum = CAPAB_BIT_ANCIENTTRANSFORM;
}
CHECK_AVAIL(msg,2);
m->pklen=buf_unprepend_uint16(msg);
return False;
}
if (type==LABEL_MSG2) return True;
- if (!consttime_memeq(m->nR,st->remoteN,NONCELEN)!=0) {
+ if (!consttime_memeq(m->nR,st->remoteN,NONCELEN)) {
*error="wrong remotely-generated nonce";
return False;
}
/* Select the transform to use */
- uint32_t remote_transforms = st->remote_capabilities & CAPAB_TRANSFORM_MASK;
- if (!remote_transforms)
+ uint32_t remote_crypto_caps = st->remote_capabilities & CAPAB_TRANSFORM_MASK;
+ if (!remote_crypto_caps)
/* old secnets only had this one transform */
- remote_transforms = 1UL << CAPAB_TRANSFORMNUM_ANCIENT;
+ remote_crypto_caps = 1UL << CAPAB_BIT_ANCIENTTRANSFORM;
+
+#define CHOOSE_CRYPTO(kind, whats) do { \
+ struct kind##_if *iface; \
+ uint32_t bit, ours = 0; \
+ int i; \
+ for (i= 0; i < st->n##kind##s; i++) { \
+ iface=st->kind##s[i]; \
+ bit = 1UL << iface->capab_bit; \
+ if (bit & remote_crypto_caps) goto kind##_found; \
+ ours |= bit; \
+ } \
+ slog(st,LOG_ERROR,"no " whats " in common" \
+ " (us %#"PRIx32"; them: %#"PRIx32")", \
+ st->local_capabilities & ours, remote_crypto_caps); \
+ return False; \
+kind##_found: \
+ st->chosen_##kind = iface; \
+} while (0)
- struct transform_if *ti;
- int i;
- for (i=0; i<st->ntransforms; i++) {
- ti=st->transforms[i];
- if ((1UL << ti->capab_transformnum) & remote_transforms)
- goto transform_found;
- }
- slog(st,LOG_ERROR,"no transforms in common"
- " (us %#"PRIx32"; them: %#"PRIx32")",
- st->local_capabilities & CAPAB_TRANSFORM_MASK,
- remote_transforms);
- return False;
- transform_found:
- st->chosen_transform=ti;
+ CHOOSE_CRYPTO(transform, "transforms");
+
+#undef CHOOSE_CRYPTO
memcpy(st->remoteN,m.nR,NONCELEN);
return True;
}
st->remote_capabilities|=m.remote_capabilities;
- struct transform_if *ti;
- int i;
- for (i=0; i<st->ntransforms; i++) {
- ti=st->transforms[i];
- if (ti->capab_transformnum == m.capab_transformnum)
- goto transform_found;
- }
- slog(st,LOG_SEC,"peer chose unknown-to-us transform %d!",
- m.capab_transformnum);
- return False;
- transform_found:
- st->chosen_transform=ti;
+#define CHOSE_CRYPTO(kind, what) do { \
+ struct kind##_if *iface; \
+ int i; \
+ for (i=0; i<st->n##kind##s; i++) { \
+ iface=st->kind##s[i]; \
+ if (iface->capab_bit == m.capab_##kind##num) \
+ goto kind##_found; \
+ } \
+ slog(st,LOG_SEC,"peer chose unknown-to-us " what " %d!", \
+ m.capab_##kind##num); \
+ return False; \
+kind##_found: \
+ st->chosen_##kind=iface; \
+} while (0)
+
+ CHOSE_CRYPTO(transform, "transform");
+
+#undef CHOSE_CRYPTO
if (!process_msg3_msg4(st,&m))
return False;
static void enter_state_run(struct site *st)
{
- slog(st,LOG_STATE,"entering state RUN");
+ slog(st,LOG_STATE,"entering state RUN%s",
+ current_valid(st) ? " (keyed)" : " (unkeyed)");
st->state=SITE_RUN;
st->timeout=0;
}
static bool_t we_have_priority(struct site *st, const struct msg *m) {
- if ((st->local_capabilities & m->remote_capabilities)
- && CAPAB_PRIORITY_MOBILE) {
+ if (st->local_capabilities & m->remote_capabilities &
+ CAPAB_PRIORITY_MOBILE) {
if (st->local_mobile) return True;
if (st-> peer_mobile) return False;
}
st->sharedsecretlen=st->sharedsecretallocd=0;
st->sharedsecret=0;
- for (i=0; i<st->ntransforms; i++) {
- struct transform_if *ti=st->transforms[i];
- uint32_t capbit = 1UL << ti->capab_transformnum;
- if (st->local_capabilities & capbit)
- slog(st,LOG_ERROR,"transformnum capability bit"
- " %d (%#"PRIx32") reused", ti->capab_transformnum, capbit);
- st->local_capabilities |= capbit;
- }
+#define SET_CAPBIT(bit) do { \
+ uint32_t capflag = 1UL << (bit); \
+ if (st->local_capabilities & capflag) \
+ slog(st,LOG_ERROR,"capability bit" \
+ " %d (%#"PRIx32") reused", (bit), capflag); \
+ st->local_capabilities |= capflag; \
+} while (0)
+
+ for (i=0; i<st->ntransforms; i++)
+ SET_CAPBIT(st->transforms[i]->capab_bit);
+
+#undef SET_CAPBIT
if (st->local_mobile || st->peer_mobile)
st->local_capabilities |= CAPAB_PRIORITY_MOBILE;