fi
-for ac_hdr in linux/if.h
+for ac_hdr in stdint.h inttypes.h
do
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
fi
done
+for ac_hdr in linux/if.h
+do
+ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
+echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
+echo "configure:1132: checking for $ac_hdr" >&5
+if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
+ echo $ac_n "(cached) $ac_c" 1>&6
+else
+ cat > conftest.$ac_ext <<EOF
+#line 1137 "configure"
+#include "confdefs.h"
+#include <$ac_hdr>
+EOF
+ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
+{ (eval echo configure:1142: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
+ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"`
+if test -z "$ac_err"; then
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=yes"
+else
+ echo "$ac_err" >&5
+ echo "configure: failed program was:" >&5
+ cat conftest.$ac_ext >&5
+ rm -rf conftest*
+ eval "ac_cv_header_$ac_safe=no"
+fi
+rm -f conftest*
+fi
+if eval "test \"`echo '$ac_cv_header_'$ac_safe`\" = yes"; then
+ echo "$ac_t""yes" 1>&6
+ ac_tr_hdr=HAVE_`echo $ac_hdr | sed 'y%abcdefghijklmnopqrstuvwxyz./-%ABCDEFGHIJKLMNOPQRSTUVWXYZ___%'`
+ cat >> confdefs.h <<EOF
+#define $ac_tr_hdr 1
+EOF
+
+else
+ echo "$ac_t""no" 1>&6
+fi
+done
+
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:1129: checking whether byte ordering is bigendian" >&5
+echo "configure:1169: checking whether byte ordering is bigendian" >&5
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro.
cat > conftest.$ac_ext <<EOF
-#line 1136 "configure"
+#line 1176 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
#endif
; return 0; }
EOF
-if { (eval echo configure:1147: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1187: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
# It does; now see whether it defined to BIG_ENDIAN or not.
cat > conftest.$ac_ext <<EOF
-#line 1151 "configure"
+#line 1191 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
#endif
; return 0; }
EOF
-if { (eval echo configure:1162: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:1202: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_bigendian=yes
else
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 1182 "configure"
+#line 1222 "configure"
#include "confdefs.h"
main () {
/* Are we little or big endian? From Harbison&Steele. */
exit (u.c[sizeof (long) - 1] == 1);
}
EOF
-if { (eval echo configure:1195: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:1235: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_bigendian=no
else
echo $ac_n "checking for mpz_init_set_str in -lgmp2""... $ac_c" 1>&6
-echo "configure:1220: checking for mpz_init_set_str in -lgmp2" >&5
+echo "configure:1260: checking for mpz_init_set_str in -lgmp2" >&5
ac_lib_var=`echo gmp2'_'mpz_init_set_str | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lgmp2 $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1228 "configure"
+#line 1268 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
mpz_init_set_str()
; return 0; }
EOF
-if { (eval echo configure:1239: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1279: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
fi
echo $ac_n "checking for yywrap in -lfl""... $ac_c" 1>&6
-echo "configure:1267: checking for yywrap in -lfl" >&5
+echo "configure:1307: checking for yywrap in -lfl" >&5
ac_lib_var=`echo fl'_'yywrap | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-lfl $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1275 "configure"
+#line 1315 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
yywrap()
; return 0; }
EOF
-if { (eval echo configure:1286: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1326: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
fi
echo $ac_n "checking for adns_init in -ladns""... $ac_c" 1>&6
-echo "configure:1314: checking for adns_init in -ladns" >&5
+echo "configure:1354: checking for adns_init in -ladns" >&5
ac_lib_var=`echo adns'_'adns_init | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
ac_save_LIBS="$LIBS"
LIBS="-ladns $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 1322 "configure"
+#line 1362 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
adns_init()
; return 0; }
EOF
-if { (eval echo configure:1333: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:1373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
#include "secnet.h"
#include "util.h"
+#include "unaligned.h"
#define SETUP_BUFFER_LEN 2048
-#define DEFAULT_KEY_LIFETIME 15000
+#define DEFAULT_KEY_LIFETIME 3600000
#define DEFAULT_SETUP_RETRIES 5
-#define DEFAULT_SETUP_TIMEOUT 500
+#define DEFAULT_SETUP_TIMEOUT 1000
#define DEFAULT_WAIT_TIME 10000
/* Each site can be in one of several possible states. */
#define LOG_SETUP_TIMEOUT 0x00000004
#define LOG_ACTIVATE_KEY 0x00000008
#define LOG_TIMEOUT_KEY 0x00000010
-#define LOG_SECURITY 0x00000020
+#define LOG_SEC 0x00000020
#define LOG_STATE 0x00000040
#define LOG_DROP 0x00000080
#define LOG_DUMP 0x00000100
#define CHECK_EMPTY(b) do { if ((b)->size!=0) return False; } while(0)
#define CHECK_TYPE(b,t) do { uint32_t type; \
CHECK_AVAIL((b),4); \
- type=*(uint32_t *)buf_unprepend((b),4); \
+ type=buf_unprepend_uint32((b)); \
if (type!=(t)) return False; } while(0)
struct msg {
st->retries=st->setup_retries;
BUF_ALLOC(&st->buffer,what);
buffer_init(&st->buffer,0);
- *(uint32_t *)buf_append(&st->buffer,4)=
- (type==LABEL_MSG1?0:st->setup_session_id);
- *(uint32_t *)buf_append(&st->buffer,4)=(uint32_t)st;
- *(uint32_t *)buf_append(&st->buffer,4)=type;
+ buf_append_uint32(&st->buffer,
+ (type==LABEL_MSG1?0:st->setup_session_id));
+ buf_append_uint32(&st->buffer,(uint32_t)st);
+ buf_append_uint32(&st->buffer,type);
buf_append_string(&st->buffer,st->localname);
buf_append_string(&st->buffer,st->remotename);
memcpy(buf_append(&st->buffer,NONCELEN),st->localN,NONCELEN);
{
m->hashstart=msg->start;
CHECK_AVAIL(msg,4);
- m->dest=*(uint32_t *)buf_unprepend(msg,4);
+ m->dest=buf_unprepend_uint32(msg);
CHECK_AVAIL(msg,4);
- m->source=*(uint32_t *)buf_unprepend(msg,4);
+ m->source=buf_unprepend_uint32(msg);
CHECK_TYPE(msg,type);
CHECK_AVAIL(msg,2);
- m->remlen=ntohs(*(uint16_t *)buf_unprepend(msg,2));
+ m->remlen=buf_unprepend_uint16(msg);
CHECK_AVAIL(msg,m->remlen);
m->remote=buf_unprepend(msg,m->remlen);
CHECK_AVAIL(msg,2);
- m->loclen=ntohs(*(uint16_t *)buf_unprepend(msg,2));
+ m->loclen=buf_unprepend_uint16(msg);
CHECK_AVAIL(msg,m->loclen);
m->local=buf_unprepend(msg,m->loclen);
CHECK_AVAIL(msg,NONCELEN);
return True;
}
CHECK_AVAIL(msg,2);
- m->pklen=ntohs(*(uint16_t *)buf_unprepend(msg,2));
+ m->pklen=buf_unprepend_uint16(msg);
CHECK_AVAIL(msg,m->pklen);
m->pk=buf_unprepend(msg,m->pklen);
m->hashlen=msg->start-m->hashstart;
CHECK_AVAIL(msg,2);
- m->siglen=ntohs(*(uint16_t *)buf_unprepend(msg,2));
+ m->siglen=buf_unprepend_uint16(msg);
CHECK_AVAIL(msg,m->siglen);
m->sig=buf_unprepend(msg,m->siglen);
CHECK_EMPTY(msg);
/* Check that the site names and our nonce have been sent
back correctly, and then store our peer's nonce. */
if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
- slog(st,LOG_SECURITY,"msg2: bad B (remote site name)");
+ slog(st,LOG_SEC,"msg2: bad B (remote site name)");
return False;
}
if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
- slog(st,LOG_SECURITY,"msg2: bad A (local site name)");
+ slog(st,LOG_SEC,"msg2: bad A (local site name)");
return False;
}
if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
- slog(st,LOG_SECURITY,"msg2: bad nA (locally generated nonce)");
+ slog(st,LOG_SEC,"msg2: bad nA (locally generated nonce)");
return False;
}
st->setup_session_id=m.source;
/* Check that the site names and nonces have been sent back
correctly */
if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
- slog(st,LOG_SECURITY,"msg3: bad A (remote site name)");
+ slog(st,LOG_SEC,"msg3: bad A (remote site name)");
return False;
}
if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
- slog(st,LOG_SECURITY,"msg3: bad B (local site name)");
+ slog(st,LOG_SEC,"msg3: bad B (local site name)");
return False;
}
if (memcmp(m.nR,st->remoteN,NONCELEN)!=0) {
- slog(st,LOG_SECURITY,"msg3: bad nA (remotely generated nonce)");
+ slog(st,LOG_SEC,"msg3: bad nA (remotely generated nonce)");
return False;
}
if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
- slog(st,LOG_SECURITY,"msg3: bad nB (locally generated nonce)");
+ slog(st,LOG_SEC,"msg3: bad nB (locally generated nonce)");
return False;
}
/* Terminate signature with a '0' - cheating, but should be ok */
m.sig[m.siglen]=0;
if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
- slog(st,LOG_SECURITY,"msg3 signature failed check!");
+ slog(st,LOG_SEC,"msg3 signature failed check!");
return False;
}
/* Check that the site names and nonces have been sent back
correctly */
if (memcmp(m.remote,st->remotename,strlen(st->remotename)!=0)) {
- slog(st,LOG_SECURITY,"msg4: bad B (remote site name)");
+ slog(st,LOG_SEC,"msg4: bad B (remote site name)");
return False;
}
if (memcmp(m.local,st->localname,strlen(st->localname)!=0)) {
- slog(st,LOG_SECURITY,"msg4: bad A (local site name)");
+ slog(st,LOG_SEC,"msg4: bad A (local site name)");
return False;
}
if (memcmp(m.nR,st->remoteN,NONCELEN)!=0) {
- slog(st,LOG_SECURITY,"msg4: bad nB (remotely generated nonce)");
+ slog(st,LOG_SEC,"msg4: bad nB (remotely generated nonce)");
return False;
}
if (memcmp(m.nL,st->localN,NONCELEN)!=0) {
- slog(st,LOG_SECURITY,"msg4: bad nA (locally generated nonce)");
+ slog(st,LOG_SEC,"msg4: bad nA (locally generated nonce)");
return False;
}
/* Terminate signature with a '0' - cheating, but should be ok */
m.sig[m.siglen]=0;
if (!st->pubkey->check(st->pubkey->st,hash,st->hash->len,m.sig)) {
- slog(st,LOG_SECURITY,"msg4 signature failed check!");
+ slog(st,LOG_SEC,"msg4 signature failed check!");
return False;
}
BUF_ALLOC(&st->buffer,"site:MSG5");
/* We are going to add three words to the transformed message */
buffer_init(&st->buffer,st->transform->max_start_pad+(4*3));
- *(uint32_t *)buf_append(&st->buffer,4)=LABEL_MSG5;
+ buf_append_uint32(&st->buffer,LABEL_MSG5);
st->new_transform->forwards(st->new_transform->st,&st->buffer,
&transform_err);
- *(uint32_t *)buf_prepend(&st->buffer,4)=LABEL_MSG5;
- *(uint32_t *)buf_prepend(&st->buffer,4)=(uint32_t)st;
- *(uint32_t *)buf_prepend(&st->buffer,4)=st->setup_session_id;
+ buf_prepend_uint32(&st->buffer,LABEL_MSG5);
+ buf_prepend_uint32(&st->buffer,(uint32_t)st);
+ buf_prepend_uint32(&st->buffer,st->setup_session_id);
st->retries=st->setup_retries;
return True;
struct msg0 *m)
{
CHECK_AVAIL(msg0,4);
- m->dest=*(uint32_t *)buf_unprepend(msg0,4);
+ m->dest=buf_unprepend_uint32(msg0);
CHECK_AVAIL(msg0,4);
- m->source=*(uint32_t *)buf_unprepend(msg0,4);
+ m->source=buf_unprepend_uint32(msg0);
CHECK_AVAIL(msg0,4);
- m->type=*(uint32_t *)buf_unprepend(msg0,4);
+ m->type=buf_unprepend_uint32(msg0);
return True;
/* Leaves transformed part of buffer untouched */
}
if (st->new_transform->reverse(st->new_transform->st,
msg5,&transform_err)) {
/* There's a problem */
- slog(st,LOG_SECURITY,"process_msg5: transform: %s",transform_err);
+ slog(st,LOG_SEC,"process_msg5: transform: %s",transform_err);
return False;
}
/* Buffer should now contain untransformed PING packet data */
CHECK_AVAIL(msg5,4);
- if ((*(uint32_t *)buf_unprepend(msg5,4))!=LABEL_MSG5) {
- slog(st,LOG_SECURITY,"MSG5/PING packet contained invalid data");
+ if (buf_unprepend_uint32(msg5)!=LABEL_MSG5) {
+ slog(st,LOG_SEC,"MSG5/PING packet contained invalid data");
return False;
}
CHECK_EMPTY(msg5);
BUF_ALLOC(&st->buffer,"site:MSG6");
/* We are going to add three words to the transformed message */
buffer_init(&st->buffer,st->transform->max_start_pad+(4*3));
- *(uint32_t *)buf_append(&st->buffer,4)=LABEL_MSG6;
+ buf_append_uint32(&st->buffer,LABEL_MSG6);
st->new_transform->forwards(st->new_transform->st,&st->buffer,
&transform_err);
- *(uint32_t *)buf_prepend(&st->buffer,4)=LABEL_MSG6;
- *(uint32_t *)buf_prepend(&st->buffer,4)=(uint32_t)st;
- *(uint32_t *)buf_prepend(&st->buffer,4)=st->setup_session_id;
+ buf_prepend_uint32(&st->buffer,LABEL_MSG6);
+ buf_prepend_uint32(&st->buffer,(uint32_t)st);
+ buf_prepend_uint32(&st->buffer,st->setup_session_id);
st->retries=1; /* Peer will retransmit MSG5 if necessary */
return True;
if (st->new_transform->reverse(st->new_transform->st,
msg6,&transform_err)) {
/* There's a problem */
- slog(st,LOG_SECURITY,"process_msg6: transform: %s",transform_err);
+ slog(st,LOG_SEC,"process_msg6: transform: %s",transform_err);
return False;
}
/* Buffer should now contain untransformed PING packet data */
CHECK_AVAIL(msg6,4);
- if ((*(uint32_t *)buf_unprepend(msg6,4))!=LABEL_MSG6) {
- slog(st,LOG_SECURITY,"MSG6/PONG packet contained invalid data");
+ if (buf_unprepend_uint32(msg6)!=LABEL_MSG6) {
+ slog(st,LOG_SEC,"MSG6/PONG packet contained invalid data");
return False;
}
CHECK_EMPTY(msg6);
if (st->current_transform->reverse(st->current_transform->st,
msg0,&transform_err)) {
/* There's a problem */
- slog(st,LOG_SECURITY,"transform: %s",transform_err);
+ slog(st,LOG_SEC,"transform: %s",transform_err);
return False;
}
CHECK_AVAIL(msg0,4);
- type=*(uint32_t *)buf_unprepend(msg0,4);
+ type=buf_unprepend_uint32(msg0);
switch(type) {
case LABEL_MSG9:
/* Deliver to netlink layer */
return True;
break;
default:
- slog(st,LOG_SECURITY,"incoming message of type %08x (unknown)",type);
+ slog(st,LOG_SEC,"incoming message of type %08x (unknown)",type);
break;
}
return False;
static void dump_packet(struct site *st, struct buffer_if *buf,
struct sockaddr_in *addr, bool_t incoming)
{
- uint32_t dest=*(uint32_t *)buf->start;
- uint32_t source=*(uint32_t *)(buf->start+4);
- uint32_t msgtype=*(uint32_t *)(buf->start+8);
+ uint32_t dest=ntohl(*(uint32_t *)buf->start);
+ uint32_t source=ntohl(*(uint32_t *)(buf->start+4));
+ uint32_t msgtype=ntohl(*(uint32_t *)(buf->start+8));
if (st->log_events & LOG_DUMP)
log(st->log,0,"(%s,%s): %s: %08x<-%08x: %08x:",
a valid key and a valid address to send it to. */
if (st->current_valid && st->peer_valid) {
/* Transform it and send it */
- *(uint32_t *)buf_prepend(buf,4)=LABEL_MSG9;
+ buf_prepend_uint32(buf,LABEL_MSG9);
st->current_transform->forwards(st->current_transform->st,
buf, &transform_err);
- *(uint32_t *)buf_prepend(buf,4)=LABEL_MSG0;
- *(uint32_t *)buf_prepend(buf,4)=(uint32_t)st;
- *(uint32_t *)buf_prepend(buf,4)=st->remote_session_id;
+ buf_prepend_uint32(buf,LABEL_MSG0);
+ buf_prepend_uint32(buf,(uint32_t)st);
+ buf_prepend_uint32(buf,st->remote_session_id);
st->comm->sendmsg(st->comm->st,buf,&st->peer);
BUF_FREE(buf);
return;
struct sockaddr_in *source)
{
struct site *st=sst;
- uint32_t dest=*(uint32_t *)buf->start;
+ uint32_t dest=ntohl(*(uint32_t *)buf->start);
if (dest==0) {
if (buf->size<(st->setupsiglen+8+NONCELEN)) return False;
return False; /* Not for us. */
}
if (dest==(uint32_t)st) {
- uint32_t msgtype=*(uint32_t *)(buf->start+8);
+ uint32_t msgtype=ntohl(*(uint32_t *)(buf->start+8));
/* Explicitly addressed to us */
if (msgtype!=LABEL_MSG0) dump_packet(st,buf,source,True);
switch (msgtype) {
case LABEL_MSG1:
/* Setup packet: should not have been explicitly addressed
to us */
- slog(st,LOG_SECURITY,"incoming explicitly addressed msg1");
+ slog(st,LOG_SEC,"incoming explicitly addressed msg1");
break;
case LABEL_MSG2:
/* Setup packet: expected only in state SENTMSG1 */
} else if (process_msg2(st,buf,source))
enter_state_sentmsg3(st);
else {
- slog(st,LOG_SECURITY,"invalid MSG2");
+ slog(st,LOG_SEC,"invalid MSG2");
}
break;
case LABEL_MSG3:
} else if (process_msg3(st,buf,source))
enter_state_sentmsg4(st);
else {
- slog(st,LOG_SECURITY,"invalid MSG3");
+ slog(st,LOG_SEC,"invalid MSG3");
}
break;
case LABEL_MSG4:
} else if (process_msg4(st,buf,source))
enter_state_sentmsg5(st);
else {
- slog(st,LOG_SECURITY,"invalid MSG4");
+ slog(st,LOG_SEC,"invalid MSG4");
}
break;
case LABEL_MSG5:
} else if (process_msg5(st,buf,source)) {
send_msg6(st);
} else {
- slog(st,LOG_SECURITY,"invalid MSG5");
+ slog(st,LOG_SEC,"invalid MSG5");
}
break;
case LABEL_MSG6:
BUF_FREE(&st->buffer); /* Free message 5 */
activate_new_key(st);
} else {
- slog(st,LOG_SECURITY,"invalid MSG6");
+ slog(st,LOG_SEC,"invalid MSG6");
}
break;
case LABEL_MSG8:
slog(st,LOG_ERROR,"received a NAK");
break;
default:
- slog(st,LOG_SECURITY,"received message of unknown type 0x%08x",
+ slog(st,LOG_SEC,"received message of unknown type 0x%08x",
msgtype);
break;
}
st->wait_timeout=dict_read_number(dict,"wait-time",
False,"site",loc,DEFAULT_WAIT_TIME);
/* XXX should be configurable */
- st->log_events=LOG_SECURITY|LOG_ERROR|
+ st->log_events=LOG_SEC|LOG_ERROR|
LOG_ACTIVATE_KEY|LOG_TIMEOUT_KEY|LOG_SETUP_INIT|LOG_SETUP_TIMEOUT;
st->tunname=safe_malloc(strlen(st->localname)+strlen(st->remotename)+5,
sprintf(st->tunname,"%s<->%s",st->localname,st->remotename);
/* The information we expect to see in incoming messages of type 1 */
+ /* XXX fix this bit for unaligned access */
st->setupsiglen=strlen(st->remotename)+strlen(st->localname)+8;
st->setupsig=safe_malloc(st->setupsiglen,"site_apply");
*(uint32_t *)&(st->setupsig[0])=LABEL_MSG1;
#include "secnet.h"
#include "util.h"
#include "serpent.h"
+#include "unaligned.h"
/* Required key length in bytes */
#define REQUIRED_KEYLEN ((512+64+32)/8)
+#ifdef WORDS_BIGENDIAN
+static inline uint32_t byteswap(uint32_t a)
+{
+ return
+ ((a&0x000000ff)<<24) |
+ ((a&0x0000ff00)<<8) |
+ ((a&0x00ff0000)>>8) |
+ ((a&0xff000000)>>24);
+}
+#endif
+
struct transform {
closure_t cl;
uint32_t line;
serpent_makekey(&ti->cryptkey,256,key);
serpent_makekey(&ti->mackey,256,key+32);
- ti->cryptiv=*(uint32_t *)(key+64);
- ti->maciv=*(uint32_t *)(key+68);
- ti->sendseq=*(uint32_t *)(key+72);
+ ti->cryptiv=ntohl(*(uint32_t *)(key+64));
+ ti->maciv=ntohl(*(uint32_t *)(key+68));
+ ti->sendseq=ntohl(*(uint32_t *)(key+72));
ti->lastrecvseq=ti->sendseq;
ti->keyed=True;
}
/* Sequence number */
- *(uint32_t *)buf_prepend(buf,4)=htonl(ti->sendseq);
+ buf_prepend_uint32(buf,ti->sendseq);
ti->sendseq++;
/* PKCS5, stolen from IWJ */
block encrypted once again. */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
+#ifdef WORDS_BIGENDIAN
+ macplain[0]=macacc[0]^byteswap(n[0]);
+ macplain[1]=macacc[1]^byteswap(n[1]);
+ macplain[2]=macacc[2]^byteswap(n[2]);
+ macplain[3]=macacc[3]^byteswap(n[3]);
+#else
macplain[0]=macacc[0]^n[0];
macplain[1]=macacc[1]^n[1];
macplain[2]=macacc[2]^n[2];
macplain[3]=macacc[3]^n[3];
+#endif
serpent_encrypt(&ti->mackey,macplain,macacc);
}
serpent_encrypt(&ti->mackey,macacc,macacc);
+#ifdef WORDS_BIGENDIAN
+ macacc[0]=byteswap(macacc[0]);
+ macacc[1]=byteswap(macacc[1]);
+ macacc[2]=byteswap(macacc[2]);
+ macacc[3]=byteswap(macacc[3]);
+#endif
memcpy(buf_append(buf,16),macacc,16);
/* Serpent-CBC. We expand the ID as for CBCMAC, do the encryption,
p=iv;
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
+#ifdef WORDS_BIGENDIAN
+ n[0]=byteswap(p[0]^n[0]);
+ n[1]=byteswap(p[1]^n[1]);
+ n[2]=byteswap(p[2]^n[2]);
+ n[3]=byteswap(p[3]^n[3]);
+#else
n[0]=p[0]^n[0];
n[1]=p[1]^n[1];
n[2]=p[2]^n[2];
n[3]=p[3]^n[3];
+#endif
serpent_encrypt(&ti->cryptkey,n,n);
p=n;
}
- *(uint32_t *)buf_prepend(buf,4)=ti->cryptiv;
+ buf_prepend_uint32(buf,ti->cryptiv);
ti->cryptiv++;
return 0;
/* CBC */
memset(iv,0,16);
- iv[0]=*(uint32_t *)buf_unprepend(buf,4);
+ iv[0]=buf_unprepend_uint32(buf);
serpent_encrypt(&ti->cryptkey,iv,iv);
/* XXX assert bufsize is multiple of blocksize */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
pct[0]=n[0]; pct[1]=n[1]; pct[2]=n[2]; pct[3]=n[3];
serpent_decrypt(&ti->cryptkey,n,n);
+#ifdef WORDS_BIGENDIAN
+ n[0]=byteswap(iv[0]^n[0]);
+ n[1]=byteswap(iv[1]^n[1]);
+ n[2]=byteswap(iv[2]^n[2]);
+ n[3]=byteswap(iv[3]^n[3]);
+#else
n[0]=iv[0]^n[0];
n[1]=iv[1]^n[1];
n[2]=iv[2]^n[2];
n[3]=iv[3]^n[3];
+#endif
iv[0]=pct[0]; iv[1]=pct[1]; iv[2]=pct[2]; iv[3]=pct[3];
}
block encrypted once again. */
for (n=(uint32_t *)buf->start; n<(uint32_t *)(buf->start+buf->size); n+=4)
{
+#ifdef WORDS_BIGENDIAN
+ macplain[0]=macacc[0]^byteswap(n[0]);
+ macplain[1]=macacc[1]^byteswap(n[1]);
+ macplain[2]=macacc[2]^byteswap(n[2]);
+ macplain[3]=macacc[3]^byteswap(n[3]);
+#else
macplain[0]=macacc[0]^n[0];
macplain[1]=macacc[1]^n[1];
macplain[2]=macacc[2]^n[2];
macplain[3]=macacc[3]^n[3];
+#endif
serpent_encrypt(&ti->mackey,macplain,macacc);
}
serpent_encrypt(&ti->mackey,macacc,macacc);
+#ifdef WORDS_BIGENDIAN
+ macacc[0]=byteswap(macacc[0]);
+ macacc[1]=byteswap(macacc[1]);
+ macacc[2]=byteswap(macacc[2]);
+ macacc[3]=byteswap(macacc[3]);
+#endif
if (memcmp(macexpected,macacc,16)!=0) {
*errmsg="invalid MAC";
return 1;
/* Sequence number must be within max_skew of lastrecvseq; lastrecvseq
is only allowed to increase. */
- seqnum=ntohl(*(uint32_t *)buf_unprepend(buf,4));
+ seqnum=buf_unprepend_uint32(buf);
skew=seqnum-ti->lastrecvseq;
if (skew<10) {
/* Ok */