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