Mercurial > hg > quicktun
diff src/proto.nacltai.c @ 0:65c01f57bdce V2.1.2
Initial commit
author | ivo <ivo@UFO-Net.nl> |
---|---|
date | Thu, 07 Oct 2010 15:53:01 +0200 |
parents | |
children | a989ecbd5f53 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/proto.nacltai.c Thu Oct 07 15:53:01 2010 +0200 @@ -0,0 +1,211 @@ +/* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. All rights reserved. + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The views and conclusions contained in the software and documentation are those of the + authors and should not be interpreted as representing official policies, either expressed + or implied, of Ivo Smits.*/ + +#include "common.c" +#include "crypto_box.h" +#include <sys/types.h> +#include <sys/time.h> + +#define uint64 unsigned long long //typedef unsigned long long uint64; + +struct tai { + uint64 x; +}; +struct taia { + struct tai sec; + unsigned long nano; /* 0...999999999 */ + unsigned long atto; /* 0...999999999 */ +}; + +struct qt_proto_data_nacltai { + unsigned char cenonce[crypto_box_NONCEBYTES], cdnonce[crypto_box_NONCEBYTES]; + unsigned char cbefore[crypto_box_BEFORENMBYTES]; + struct taia cdtaip, cdtaic; +}; + +#define noncelength sizeof(struct taia) +#define nonceoffset (crypto_box_NONCEBYTES - noncelength) +/*static unsigned char cbefore[crypto_box_BEFORENMBYTES]; +static unsigned char buffer1[MAX_PACKET_LEN+crypto_box_ZEROBYTES], buffer2[MAX_PACKET_LEN+crypto_box_ZEROBYTES]; +static const unsigned char* buffer1offset = buffer1 + crypto_box_ZEROBYTES; +static const unsigned char* buffer2offset = buffer2 + crypto_box_BOXZEROBYTES - noncelength;*/ +static const int overhead = crypto_box_BOXZEROBYTES + noncelength; + +void tai_pack(char *s, struct tai *t) { + uint64 x; + x = t->x; + s[7] = x & 255; x >>= 8; + s[6] = x & 255; x >>= 8; + s[5] = x & 255; x >>= 8; + s[4] = x & 255; x >>= 8; + s[3] = x & 255; x >>= 8; + s[2] = x & 255; x >>= 8; + s[1] = x & 255; x >>= 8; + s[0] = x; +} +void tai_unpack(char *s, struct tai *t) { + uint64 x; + x = (unsigned char) s[0]; + x <<= 8; x += (unsigned char) s[1]; + x <<= 8; x += (unsigned char) s[2]; + x <<= 8; x += (unsigned char) s[3]; + x <<= 8; x += (unsigned char) s[4]; + x <<= 8; x += (unsigned char) s[5]; + x <<= 8; x += (unsigned char) s[6]; + x <<= 8; x += (unsigned char) s[7]; + t->x = x; +} +void taia_pack(char *s, struct taia *t) { + unsigned long x; + tai_pack(s,&t->sec); + s += 8; + x = t->atto; + s[7] = x & 255; x >>= 8; + s[6] = x & 255; x >>= 8; + s[5] = x & 255; x >>= 8; + s[4] = x; + x = t->nano; + s[3] = x & 255; x >>= 8; + s[2] = x & 255; x >>= 8; + s[1] = x & 255; x >>= 8; + s[0] = x; +} +void taia_unpack(char *s, struct taia *t) { + unsigned long x; + tai_unpack(s,&t->sec); + s += 8; + x = (unsigned char) s[4]; + x <<= 8; x += (unsigned char) s[5]; + x <<= 8; x += (unsigned char) s[6]; + x <<= 8; x += (unsigned char) s[7]; + t->atto = x; + x = (unsigned char) s[0]; + x <<= 8; x += (unsigned char) s[1]; + x <<= 8; x += (unsigned char) s[2]; + x <<= 8; x += (unsigned char) s[3]; + t->nano = x; +} + +void taia_now(struct taia *t) { + struct timeval now; + gettimeofday(&now,(struct timezone *) 0); + t->sec.x = 4611686018427387914ULL + (uint64) now.tv_sec; + t->nano = 1000 * now.tv_usec + 500; + t->atto = 0; +} + +extern crypto_scalarmult_curve25519_base(unsigned char *pk, unsigned char *sk); + +static int encode(struct qtsession* sess, char* raw, char* enc, int len) { + struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; + memset(raw, 0, crypto_box_ZEROBYTES); + taia_now(&d->cdtaic); + taia_pack(d->cenonce + nonceoffset, &(d->cdtaic)); + if (crypto_box_afternm(enc, raw, len + crypto_box_ZEROBYTES, d->cenonce, d->cbefore)) return errorexit("Crypto failed"); + memcpy((void*)(enc + crypto_box_BOXZEROBYTES - noncelength), d->cenonce + nonceoffset, noncelength); + len += overhead; + return len; +} + +static int decode(struct qtsession* sess, char* enc, char* raw, int len) { + struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; + int i; + if (len < overhead) { + fprintf(stderr, "Short packet received: %d\n", len); + return 0; + } + len -= overhead; + taia_unpack((char*)(enc + crypto_box_BOXZEROBYTES - noncelength), &(d->cdtaic)); + if (d->cdtaic.sec.x <= d->cdtaip.sec.x || d->cdtaic.nano <= d->cdtaip.nano || d->cdtaic.atto <= d->cdtaip.atto) { + fprintf(stderr, "Timestamp going back, ignoring packet\n"); + return 0; + } + memcpy(d->cdnonce + nonceoffset, enc + crypto_box_BOXZEROBYTES - noncelength, noncelength); + memset(enc, 0, crypto_box_BOXZEROBYTES); + if (i = crypto_box_open_afternm(raw, enc, len + crypto_box_ZEROBYTES, d->cdnonce, d->cbefore)) { + fprintf(stderr, "Decryption failed len=%d result=%d\n", len, i); + return 0; + } + d->cdtaip = d->cdtaic; + return len; +} + +static int init(struct qtsession* sess) { + struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; + char* envval; + printf("Initializing cryptography...\n"); + unsigned char cownpublickey[crypto_box_PUBLICKEYBYTES], cpublickey[crypto_box_PUBLICKEYBYTES], csecretkey[crypto_box_SECRETKEYBYTES]; + if (!(envval = getconf("PUBLIC_KEY"))) return errorexit("Missing PUBLIC_KEY"); + if (strlen(envval) != 2*crypto_box_PUBLICKEYBYTES) return errorexit("PUBLIC_KEY length"); + hex2bin(cpublickey, envval, crypto_box_PUBLICKEYBYTES); + if (!(envval = getconf("PRIVATE_KEY"))) return errorexit("Missing PRIVATE_KEY"); + if (strlen(envval) != 2*crypto_box_PUBLICKEYBYTES) return errorexit("PRIVATE_KEY length"); + hex2bin(csecretkey, envval, crypto_box_SECRETKEYBYTES); + crypto_box_beforenm(d->cbefore, cpublickey, csecretkey); + + memset(d->cenonce, 0, crypto_box_NONCEBYTES); + memset(d->cdnonce, 0, crypto_box_NONCEBYTES); + + crypto_scalarmult(cownpublickey, csecretkey); + + if (envval = getenv("TIME_WINDOW")) { + taia_now(&d->cdtaip); + d->cdtaip.sec.x -= atol(envval); + } else { + printf("Warning: TIME_WINDOW not set, risking an initial replay attack\n"); + } + if (envval = getenv("ROLE")) { + d->cenonce[nonceoffset-1] = atoi(envval) ? 1 : 0; + } else { + d->cenonce[nonceoffset-1] = memcmp(cpublickey, cownpublickey, crypto_box_PUBLICKEYBYTES) ? 1 : 0; + } + d->cdnonce[nonceoffset-1] = d->cenonce[nonceoffset-1] ? 0 : 1; +} + +#ifdef COMBINED_BINARY + int tunmain_nacltai() { +#else + int tunmain() { +#endif + struct qtproto p = { + 1, + MAX_PACKET_LEN + crypto_box_ZEROBYTES, + MAX_PACKET_LEN + crypto_box_ZEROBYTES, + crypto_box_ZEROBYTES, + crypto_box_BOXZEROBYTES - noncelength, + encode, + decode, + init, + sizeof(struct qt_proto_data_nacltai), + }; + return qtrun(&p); +} + +#ifndef COMBINED_BINARY +int main() { + print_header(); + return tunmain(); +} +#endif