Mercurial > hg > quicktun
comparison src/proto.nacltai.c @ 44:55f379f0a650
Fixed/improved handling of timestamp in nonce in nacltai protocol
author | Ivo Smits <Ivo@UCIS.nl> |
---|---|
date | Fri, 17 May 2013 16:09:49 +0200 |
parents | 4adbd9b67fe2 |
children | 3115f8af98bb |
comparison
equal
deleted
inserted
replaced
43:4adbd9b67fe2 | 44:55f379f0a650 |
---|---|
27 #include "crypto_box_curve25519xsalsa20poly1305.h" | 27 #include "crypto_box_curve25519xsalsa20poly1305.h" |
28 #include "crypto_scalarmult_curve25519.h" | 28 #include "crypto_scalarmult_curve25519.h" |
29 #include <sys/types.h> | 29 #include <sys/types.h> |
30 #include <sys/time.h> | 30 #include <sys/time.h> |
31 | 31 |
32 #define uint64 unsigned long long //typedef unsigned long long uint64; | |
33 | |
34 struct tai { | |
35 uint64 x; | |
36 }; | |
37 struct taia { | |
38 struct tai sec; | |
39 unsigned long nano; /* 0...999999999 */ | |
40 unsigned long atto; /* 0...999999999 */ | |
41 }; | |
42 | |
43 struct qt_proto_data_nacltai { | 32 struct qt_proto_data_nacltai { |
44 unsigned char cenonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES], cdnonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES]; | 33 unsigned char cenonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES], cdnonce[crypto_box_curve25519xsalsa20poly1305_NONCEBYTES]; |
45 unsigned char cbefore[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; | 34 unsigned char cbefore[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; |
46 struct taia cdtaip, cdtaie; | 35 unsigned char cdtaipp[16]; |
47 }; | 36 }; |
48 | 37 |
49 #define noncelength 16 | 38 #define noncelength 16 |
50 #define nonceoffset (crypto_box_curve25519xsalsa20poly1305_NONCEBYTES - noncelength) | 39 #define nonceoffset (crypto_box_curve25519xsalsa20poly1305_NONCEBYTES - noncelength) |
51 /*static unsigned char cbefore[crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES]; | |
52 static unsigned char buffer1[MAX_PACKET_LEN+crypto_box_curve25519xsalsa20poly1305_ZEROBYTES], buffer2[MAX_PACKET_LEN+crypto_box_curve25519xsalsa20poly1305_ZEROBYTES]; | |
53 static const unsigned char* buffer1offset = buffer1 + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES; | |
54 static const unsigned char* buffer2offset = buffer2 + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength;*/ | |
55 static const int overhead = crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + noncelength; | 40 static const int overhead = crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES + noncelength; |
56 | 41 |
57 void tai_pack(char *s, struct tai *t) { | 42 static void taia_now_packed(unsigned char* b, int secoffset) { |
58 uint64 x; | 43 struct timeval now; |
59 x = t->x; | 44 gettimeofday(&now, NULL); |
60 s[7] = x & 255; x >>= 8; | 45 u_int64_t sec = 4611686018427387914ULL + (u_int64_t)now.tv_sec + secoffset; |
61 s[6] = x & 255; x >>= 8; | 46 b[0] = (sec >> 56) & 0xff; |
62 s[5] = x & 255; x >>= 8; | 47 b[1] = (sec >> 48) & 0xff; |
63 s[4] = x & 255; x >>= 8; | 48 b[2] = (sec >> 40) & 0xff; |
64 s[3] = x & 255; x >>= 8; | 49 b[3] = (sec >> 32) & 0xff; |
65 s[2] = x & 255; x >>= 8; | 50 b[4] = (sec >> 24) & 0xff; |
66 s[1] = x & 255; x >>= 8; | 51 b[5] = (sec >> 16) & 0xff; |
67 s[0] = x; | 52 b[6] = (sec >> 8) & 0xff; |
68 } | 53 b[7] = (sec >> 0) & 0xff; |
69 void tai_unpack(char *s, struct tai *t) { | 54 u_int32_t nano = 1000 * now.tv_usec + 500; |
70 uint64 x; | 55 b[8] = (nano >> 24) & 0xff; |
71 x = (unsigned char) s[0]; | 56 b[9] = (nano >> 16) & 0xff; |
72 x <<= 8; x += (unsigned char) s[1]; | 57 b[10] = (nano >> 8) & 0xff; |
73 x <<= 8; x += (unsigned char) s[2]; | 58 b[11] = (nano >> 0) & 0xff; |
74 x <<= 8; x += (unsigned char) s[3]; | 59 ++b[15] == 0 && ++b[14] == 0 && ++b[13] == 0 && ++b[12] == 0; |
75 x <<= 8; x += (unsigned char) s[4]; | |
76 x <<= 8; x += (unsigned char) s[5]; | |
77 x <<= 8; x += (unsigned char) s[6]; | |
78 x <<= 8; x += (unsigned char) s[7]; | |
79 t->x = x; | |
80 } | |
81 void taia_pack(char *s, struct taia *t) { | |
82 unsigned long x; | |
83 tai_pack(s,&t->sec); | |
84 s += 8; | |
85 x = t->atto; | |
86 s[7] = x & 255; x >>= 8; | |
87 s[6] = x & 255; x >>= 8; | |
88 s[5] = x & 255; x >>= 8; | |
89 s[4] = x; | |
90 x = t->nano; | |
91 s[3] = x & 255; x >>= 8; | |
92 s[2] = x & 255; x >>= 8; | |
93 s[1] = x & 255; x >>= 8; | |
94 s[0] = x; | |
95 } | |
96 void taia_unpack(char *s, struct taia *t) { | |
97 unsigned long x; | |
98 tai_unpack(s,&t->sec); | |
99 s += 8; | |
100 x = (unsigned char) s[4]; | |
101 x <<= 8; x += (unsigned char) s[5]; | |
102 x <<= 8; x += (unsigned char) s[6]; | |
103 x <<= 8; x += (unsigned char) s[7]; | |
104 t->atto = x; | |
105 x = (unsigned char) s[0]; | |
106 x <<= 8; x += (unsigned char) s[1]; | |
107 x <<= 8; x += (unsigned char) s[2]; | |
108 x <<= 8; x += (unsigned char) s[3]; | |
109 t->nano = x; | |
110 } | 60 } |
111 | 61 |
112 void taia_now(struct taia *t) { | 62 //Packet format: <16 bytes taia packed timestamp><16 bytes checksum><n bytes encrypted data> |
113 struct timeval now; | |
114 gettimeofday(&now,(struct timezone *) 0); | |
115 t->sec.x = 4611686018427387914ULL + (uint64) now.tv_sec; | |
116 t->nano = 1000 * now.tv_usec + 500; | |
117 t->atto++; | |
118 } | |
119 | 63 |
120 static int encode(struct qtsession* sess, char* raw, char* enc, int len) { | 64 static int encode(struct qtsession* sess, char* raw, char* enc, int len) { |
121 if (debug) fprintf(stderr, "Encoding packet of %d bytes from %p to %p\n", len, raw, enc); | 65 if (debug) fprintf(stderr, "Encoding packet of %d bytes from %p to %p\n", len, raw, enc); |
122 struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; | 66 struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; |
123 memset(raw, 0, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES); | 67 memset(raw, 0, crypto_box_curve25519xsalsa20poly1305_ZEROBYTES); |
124 taia_now(&d->cdtaie); | 68 taia_now_packed(d->cenonce + nonceoffset, 0); |
125 taia_pack(d->cenonce + nonceoffset, &(d->cdtaie)); | |
126 if (crypto_box_curve25519xsalsa20poly1305_afternm(enc, raw, len + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cenonce, d->cbefore)) return errorexit("Encryption failed"); | 69 if (crypto_box_curve25519xsalsa20poly1305_afternm(enc, raw, len + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cenonce, d->cbefore)) return errorexit("Encryption failed"); |
127 memcpy((void*)(enc + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength), d->cenonce + nonceoffset, noncelength); | 70 memcpy((void*)(enc + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength), d->cenonce + nonceoffset, noncelength); |
128 len += overhead; | 71 len += overhead; |
129 if (debug) fprintf(stderr, "Encoded packet of %d bytes from %p to %p\n", len, raw, enc); | 72 if (debug) fprintf(stderr, "Encoded packet of %d bytes from %p to %p\n", len, raw, enc); |
130 return len; | 73 return len; |
131 } | 74 } |
132 | 75 |
133 static int decode(struct qtsession* sess, char* enc, char* raw, int len) { | 76 static int decode(struct qtsession* sess, char* enc, char* raw, int len) { |
134 if (debug) fprintf(stderr, "Decoding packet of %d bytes from %p to %p\n", len, enc, raw); | 77 if (debug) fprintf(stderr, "Decoding packet of %d bytes from %p to %p\n", len, enc, raw); |
135 struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; | 78 struct qt_proto_data_nacltai* d = (struct qt_proto_data_nacltai*)sess->protocol_data; |
136 struct taia cdtaic; | |
137 int i; | 79 int i; |
138 if (len < overhead) { | 80 if (len < overhead) { |
139 fprintf(stderr, "Short packet received: %d\n", len); | 81 fprintf(stderr, "Short packet received: %d\n", len); |
140 return -1; | 82 return -1; |
141 } | 83 } |
142 len -= overhead; | 84 len -= overhead; |
143 taia_unpack((char*)(enc + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength), &cdtaic); | 85 if (memcmp(enc, d->cdtaipp, 16) <= 0) { |
144 if (cdtaic.sec.x <= d->cdtaip.sec.x && cdtaic.nano <= d->cdtaip.nano && cdtaic.atto <= d->cdtaip.atto) { | |
145 fprintf(stderr, "Timestamp going back, ignoring packet\n"); | 86 fprintf(stderr, "Timestamp going back, ignoring packet\n"); |
146 return -1; | 87 return -1; |
147 } | 88 } |
148 memcpy(d->cdnonce + nonceoffset, enc + crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES - noncelength, noncelength); | 89 memcpy(d->cdnonce + nonceoffset, enc, noncelength); |
149 memset(enc, 0, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES); | 90 memset(enc, 0, crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES); |
150 if (i = crypto_box_curve25519xsalsa20poly1305_open_afternm(raw, enc, len + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cdnonce, d->cbefore)) { | 91 if (i = crypto_box_curve25519xsalsa20poly1305_open_afternm(raw, enc, len + crypto_box_curve25519xsalsa20poly1305_ZEROBYTES, d->cdnonce, d->cbefore)) { |
151 fprintf(stderr, "Decryption failed len=%d result=%d\n", len, i); | 92 fprintf(stderr, "Decryption failed len=%d result=%d\n", len, i); |
152 return -1; | 93 return -1; |
153 } | 94 } |
154 d->cdtaip = cdtaic; | 95 memcpy(d->cdtaipp, d->cdnonce + nonceoffset, 16); |
155 if (debug) fprintf(stderr, "Decoded packet of %d bytes from %p to %p\n", len, enc, raw); | 96 if (debug) fprintf(stderr, "Decoded packet of %d bytes from %p to %p\n", len, enc, raw); |
156 return len; | 97 return len; |
157 } | 98 } |
158 | 99 |
159 static int init(struct qtsession* sess) { | 100 static int init(struct qtsession* sess) { |
185 } | 126 } |
186 crypto_box_curve25519xsalsa20poly1305_beforenm(d->cbefore, cpublickey, csecretkey); | 127 crypto_box_curve25519xsalsa20poly1305_beforenm(d->cbefore, cpublickey, csecretkey); |
187 | 128 |
188 memset(d->cenonce, 0, crypto_box_curve25519xsalsa20poly1305_NONCEBYTES); | 129 memset(d->cenonce, 0, crypto_box_curve25519xsalsa20poly1305_NONCEBYTES); |
189 memset(d->cdnonce, 0, crypto_box_curve25519xsalsa20poly1305_NONCEBYTES); | 130 memset(d->cdnonce, 0, crypto_box_curve25519xsalsa20poly1305_NONCEBYTES); |
131 memset(d->cdtaipp, 0, 16); | |
190 | 132 |
191 crypto_scalarmult_curve25519_base(cownpublickey, csecretkey); | 133 crypto_scalarmult_curve25519_base(cownpublickey, csecretkey); |
192 | 134 |
193 if (envval = getconf("TIME_WINDOW")) { | 135 if (envval = getconf("TIME_WINDOW")) { |
194 taia_now(&d->cdtaip); | 136 taia_now_packed(d->cdtaipp, -atol(envval)); |
195 d->cdtaip.sec.x -= atol(envval); | |
196 } else { | 137 } else { |
197 fprintf(stderr, "Warning: TIME_WINDOW not set, risking an initial replay attack\n"); | 138 fprintf(stderr, "Warning: TIME_WINDOW not set, risking an initial replay attack\n"); |
198 } | 139 } |
199 int role = memcmp(cownpublickey, cpublickey, crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES); | 140 int role = memcmp(cownpublickey, cpublickey, crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES); |
200 if (envval = getconf("ROLE")) role = atoi(envval) ? 1 : -1; | 141 if (envval = getconf("ROLE")) role = atoi(envval) ? 1 : -1; |