Mercurial > hg > quicktun
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:65c01f57bdce |
---|---|
1 /* Copyright 2010 Ivo Smits <Ivo@UCIS.nl>. All rights reserved. | |
2 Redistribution and use in source and binary forms, with or without modification, are | |
3 permitted provided that the following conditions are met: | |
4 | |
5 1. Redistributions of source code must retain the above copyright notice, this list of | |
6 conditions and the following disclaimer. | |
7 | |
8 2. Redistributions in binary form must reproduce the above copyright notice, this list | |
9 of conditions and the following disclaimer in the documentation and/or other materials | |
10 provided with the distribution. | |
11 | |
12 THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED | |
13 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND | |
14 FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR | |
15 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR | |
16 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR | |
17 SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON | |
18 ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
19 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF | |
20 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
21 | |
22 The views and conclusions contained in the software and documentation are those of the | |
23 authors and should not be interpreted as representing official policies, either expressed | |
24 or implied, of Ivo Smits.*/ | |
25 | |
26 #include "common.c" | |
27 #include "crypto_box.h" | |
28 #include <sys/types.h> | |
29 #include <sys/time.h> | |
30 | |
31 #define uint64 unsigned long long //typedef unsigned long long uint64; | |
32 | |
33 struct tai { | |
34 uint64 x; | |
35 }; | |
36 struct taia { | |
37 struct tai sec; | |
38 unsigned long nano; /* 0...999999999 */ | |
39 unsigned long atto; /* 0...999999999 */ | |
40 }; | |
41 | |
42 struct qt_proto_data_nacltai { | |
43 unsigned char cenonce[crypto_box_NONCEBYTES], cdnonce[crypto_box_NONCEBYTES]; | |
44 unsigned char cbefore[crypto_box_BEFORENMBYTES]; | |
45 struct taia cdtaip, cdtaic; | |
46 }; | |
47 | |
48 #define noncelength sizeof(struct taia) | |
49 #define nonceoffset (crypto_box_NONCEBYTES - noncelength) | |
50 /*static unsigned char cbefore[crypto_box_BEFORENMBYTES]; | |
51 static unsigned char buffer1[MAX_PACKET_LEN+crypto_box_ZEROBYTES], buffer2[MAX_PACKET_LEN+crypto_box_ZEROBYTES]; | |
52 static const unsigned char* buffer1offset = buffer1 + crypto_box_ZEROBYTES; | |
53 static const unsigned char* buffer2offset = buffer2 + crypto_box_BOXZEROBYTES - noncelength;*/ | |
54 static const int overhead = crypto_box_BOXZEROBYTES + noncelength; | |
55 | |
56 void tai_pack(char *s, struct tai *t) { | |
57 uint64 x; | |
58 x = t->x; | |
59 s[7] = x & 255; x >>= 8; | |
60 s[6] = x & 255; x >>= 8; | |
61 s[5] = x & 255; x >>= 8; | |
62 s[4] = x & 255; x >>= 8; | |
63 s[3] = x & 255; x >>= 8; | |
64 s[2] = x & 255; x >>= 8; | |
65 s[1] = x & 255; x >>= 8; | |
66 s[0] = x; | |
67 } | |
68 void tai_unpack(char *s, struct tai *t) { | |
69 uint64 x; | |
70 x = (unsigned char) s[0]; | |
71 x <<= 8; x += (unsigned char) s[1]; | |
72 x <<= 8; x += (unsigned char) s[2]; | |
73 x <<= 8; x += (unsigned char) s[3]; | |
74 x <<= 8; x += (unsigned char) s[4]; | |
75 x <<= 8; x += (unsigned char) s[5]; | |
76 x <<= 8; x += (unsigned char) s[6]; | |
77 x <<= 8; x += (unsigned char) s[7]; | |
78 t->x = x; | |
79 } | |
80 void taia_pack(char *s, struct taia *t) { | |
81 unsigned long x; | |
82 tai_pack(s,&t->sec); | |
83 s += 8; | |
84 x = t->atto; | |
85 s[7] = x & 255; x >>= 8; | |
86 s[6] = x & 255; x >>= 8; | |
87 s[5] = x & 255; x >>= 8; | |
88 s[4] = x; | |
89 x = t->nano; | |
90 s[3] = x & 255; x >>= 8; | |
91 s[2] = x & 255; x >>= 8; | |
92 s[1] = x & 255; x >>= 8; | |
93 s[0] = x; | |
94 } | |
95 void taia_unpack(char *s, struct taia *t) { | |
96 unsigned long x; | |
97 tai_unpack(s,&t->sec); | |
98 s += 8; | |
99 x = (unsigned char) s[4]; | |
100 x <<= 8; x += (unsigned char) s[5]; | |
101 x <<= 8; x += (unsigned char) s[6]; | |
102 x <<= 8; x += (unsigned char) s[7]; | |
103 t->atto = x; | |
104 x = (unsigned char) s[0]; | |
105 x <<= 8; x += (unsigned char) s[1]; | |
106 x <<= 8; x += (unsigned char) s[2]; | |
107 x <<= 8; x += (unsigned char) s[3]; | |
108 t->nano = x; | |
109 } | |
110 | |
111 void taia_now(struct taia *t) { | |
112 struct timeval now; | |
113 gettimeofday(&now,(struct timezone *) 0); | |
114 t->sec.x = 4611686018427387914ULL + (uint64) now.tv_sec; | |
115 t->nano = 1000 * now.tv_usec + 500; | |
116 t->atto = 0; | |
117 } | |
118 | |
119 extern crypto_scalarmult_curve25519_base(unsigned char *pk, unsigned char *sk); | |
120 | |
121 static int encode(struct qtsession* sess, char* raw, char* enc, int len) { | |
122 struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; | |
123 memset(raw, 0, crypto_box_ZEROBYTES); | |
124 taia_now(&d->cdtaic); | |
125 taia_pack(d->cenonce + nonceoffset, &(d->cdtaic)); | |
126 if (crypto_box_afternm(enc, raw, len + crypto_box_ZEROBYTES, d->cenonce, d->cbefore)) return errorexit("Crypto failed"); | |
127 memcpy((void*)(enc + crypto_box_BOXZEROBYTES - noncelength), d->cenonce + nonceoffset, noncelength); | |
128 len += overhead; | |
129 return len; | |
130 } | |
131 | |
132 static int decode(struct qtsession* sess, char* enc, char* raw, int len) { | |
133 struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; | |
134 int i; | |
135 if (len < overhead) { | |
136 fprintf(stderr, "Short packet received: %d\n", len); | |
137 return 0; | |
138 } | |
139 len -= overhead; | |
140 taia_unpack((char*)(enc + crypto_box_BOXZEROBYTES - noncelength), &(d->cdtaic)); | |
141 if (d->cdtaic.sec.x <= d->cdtaip.sec.x || d->cdtaic.nano <= d->cdtaip.nano || d->cdtaic.atto <= d->cdtaip.atto) { | |
142 fprintf(stderr, "Timestamp going back, ignoring packet\n"); | |
143 return 0; | |
144 } | |
145 memcpy(d->cdnonce + nonceoffset, enc + crypto_box_BOXZEROBYTES - noncelength, noncelength); | |
146 memset(enc, 0, crypto_box_BOXZEROBYTES); | |
147 if (i = crypto_box_open_afternm(raw, enc, len + crypto_box_ZEROBYTES, d->cdnonce, d->cbefore)) { | |
148 fprintf(stderr, "Decryption failed len=%d result=%d\n", len, i); | |
149 return 0; | |
150 } | |
151 d->cdtaip = d->cdtaic; | |
152 return len; | |
153 } | |
154 | |
155 static int init(struct qtsession* sess) { | |
156 struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; | |
157 char* envval; | |
158 printf("Initializing cryptography...\n"); | |
159 unsigned char cownpublickey[crypto_box_PUBLICKEYBYTES], cpublickey[crypto_box_PUBLICKEYBYTES], csecretkey[crypto_box_SECRETKEYBYTES]; | |
160 if (!(envval = getconf("PUBLIC_KEY"))) return errorexit("Missing PUBLIC_KEY"); | |
161 if (strlen(envval) != 2*crypto_box_PUBLICKEYBYTES) return errorexit("PUBLIC_KEY length"); | |
162 hex2bin(cpublickey, envval, crypto_box_PUBLICKEYBYTES); | |
163 if (!(envval = getconf("PRIVATE_KEY"))) return errorexit("Missing PRIVATE_KEY"); | |
164 if (strlen(envval) != 2*crypto_box_PUBLICKEYBYTES) return errorexit("PRIVATE_KEY length"); | |
165 hex2bin(csecretkey, envval, crypto_box_SECRETKEYBYTES); | |
166 crypto_box_beforenm(d->cbefore, cpublickey, csecretkey); | |
167 | |
168 memset(d->cenonce, 0, crypto_box_NONCEBYTES); | |
169 memset(d->cdnonce, 0, crypto_box_NONCEBYTES); | |
170 | |
171 crypto_scalarmult(cownpublickey, csecretkey); | |
172 | |
173 if (envval = getenv("TIME_WINDOW")) { | |
174 taia_now(&d->cdtaip); | |
175 d->cdtaip.sec.x -= atol(envval); | |
176 } else { | |
177 printf("Warning: TIME_WINDOW not set, risking an initial replay attack\n"); | |
178 } | |
179 if (envval = getenv("ROLE")) { | |
180 d->cenonce[nonceoffset-1] = atoi(envval) ? 1 : 0; | |
181 } else { | |
182 d->cenonce[nonceoffset-1] = memcmp(cpublickey, cownpublickey, crypto_box_PUBLICKEYBYTES) ? 1 : 0; | |
183 } | |
184 d->cdnonce[nonceoffset-1] = d->cenonce[nonceoffset-1] ? 0 : 1; | |
185 } | |
186 | |
187 #ifdef COMBINED_BINARY | |
188 int tunmain_nacltai() { | |
189 #else | |
190 int tunmain() { | |
191 #endif | |
192 struct qtproto p = { | |
193 1, | |
194 MAX_PACKET_LEN + crypto_box_ZEROBYTES, | |
195 MAX_PACKET_LEN + crypto_box_ZEROBYTES, | |
196 crypto_box_ZEROBYTES, | |
197 crypto_box_BOXZEROBYTES - noncelength, | |
198 encode, | |
199 decode, | |
200 init, | |
201 sizeof(struct qt_proto_data_nacltai), | |
202 }; | |
203 return qtrun(&p); | |
204 } | |
205 | |
206 #ifndef COMBINED_BINARY | |
207 int main() { | |
208 print_header(); | |
209 return tunmain(); | |
210 } | |
211 #endif |