docs: authors: add Doug as minor contr. (thanks)
[netsniff-ng.git] / src / curve.h
blob6909d78cd399f05487150e8b8814a8d1c2fae349
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2011 Daniel Borkmann.
5 * Subject to the GPL, version 2.
6 */
8 #ifndef CURVE_H
9 #define CURVE_H
11 #include <stdint.h>
12 #include <sys/time.h>
14 #include "locking.h"
15 #include "mtrand.h"
16 #include "built_in.h"
17 #include "crypto_box_curve25519xsalsa20poly1305.h"
19 /* Some parts derived from public domain code from curveprotect project */
21 struct tai {
22 uint64_t x;
25 struct taia {
26 struct tai sec;
27 uint32_t nano; /* 0...999999999 */
28 uint32_t atto; /* 0...999999999 */
31 /* Delay tolerance for packets! */
32 static struct taia tolerance_taia = {
33 .sec.x = 0,
34 .nano = 700000000ULL,
35 .atto = 0,
38 #define crypto_box_zerobytes crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
39 #define crypto_box_boxzerobytes crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
41 #define crypto_box_noncebytes crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
42 #define crypto_box_beforenmbytes crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
44 /* Per connection */
45 struct curve25519_proto {
46 unsigned char enonce[crypto_box_noncebytes] __aligned_16;
47 unsigned char dnonce[crypto_box_noncebytes] __aligned_16;
48 unsigned char key[crypto_box_noncebytes] __aligned_16;
51 /* Per thread */
52 struct curve25519_struct {
53 /* Encode buffer */
54 size_t enc_buf_size;
55 unsigned char *enc_buf;
56 struct spinlock enc_lock;
57 /* Decode buffer */
58 size_t dec_buf_size;
59 unsigned char *dec_buf;
60 struct spinlock dec_lock;
63 extern void curve25519_selftest(void);
64 extern int curve25519_pubkey_hexparse_32(unsigned char *y, size_t ylen,
65 const char *x, size_t len);
66 extern int curve25519_alloc_or_maybe_die(struct curve25519_struct *c);
67 extern void curve25519_free(void *vc);
68 extern int curve25519_proto_init(struct curve25519_proto *p,
69 unsigned char *pubkey_remote, size_t len,
70 char *home, int server);
71 extern ssize_t curve25519_encode(struct curve25519_struct *c,
72 struct curve25519_proto *p,
73 unsigned char *plaintext, size_t size,
74 unsigned char **chipertext);
75 extern ssize_t curve25519_decode(struct curve25519_struct *c,
76 struct curve25519_proto *p,
77 unsigned char *chipertext, size_t size,
78 unsigned char **plaintext,
79 struct taia *arrival_taia);
81 static inline void tai_pack(unsigned char *s, struct tai *t)
83 uint64_t x;
85 x = t->x;
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 & 255; x >>= 8;
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;
96 static inline void tai_unpack(unsigned char *s, struct tai *t)
98 uint64_t x;
100 x = (unsigned char) s[0];
101 x <<= 8; x += (unsigned char) s[1];
102 x <<= 8; x += (unsigned char) s[2];
103 x <<= 8; x += (unsigned char) s[3];
104 x <<= 8; x += (unsigned char) s[4];
105 x <<= 8; x += (unsigned char) s[5];
106 x <<= 8; x += (unsigned char) s[6];
107 x <<= 8; x += (unsigned char) s[7];
108 t->x = x;
111 static inline void taia_pack(unsigned char *s, struct taia *t)
113 unsigned long x;
115 tai_pack(s, &t->sec);
116 s += 8;
117 x = t->atto;
118 s[7] = x & 255; x >>= 8;
119 s[6] = x & 255; x >>= 8;
120 s[5] = x & 255; x >>= 8;
121 s[4] = x;
122 x = t->nano;
123 s[3] = x & 255; x >>= 8;
124 s[2] = x & 255; x >>= 8;
125 s[1] = x & 255; x >>= 8;
126 s[0] = x;
129 static inline void taia_unpack(unsigned char *s, struct taia *t)
131 unsigned long x;
133 tai_unpack(s, &t->sec);
134 s += 8;
135 x = (unsigned char) s[4];
136 x <<= 8; x += (unsigned char) s[5];
137 x <<= 8; x += (unsigned char) s[6];
138 x <<= 8; x += (unsigned char) s[7];
139 t->atto = x;
140 x = (unsigned char) s[0];
141 x <<= 8; x += (unsigned char) s[1];
142 x <<= 8; x += (unsigned char) s[2];
143 x <<= 8; x += (unsigned char) s[3];
144 t->nano = x;
147 #define tai_unix(t, u) ((void) ((t)->x = 4611686018427387914ULL + (uint64_t) (u)))
149 static inline void taia_now(struct taia *t)
151 struct timeval now;
153 gettimeofday(&now, NULL);
154 tai_unix(&t->sec, now.tv_sec);
155 t->nano = 1000 * now.tv_usec + 500;
156 t->atto = mt_rand_int32();
159 /* XXX: breaks tai encapsulation */
161 /* calcs u - v */
162 static inline void taia_sub(struct taia *res,
163 const struct taia *u,
164 const struct taia *v)
166 unsigned long unano = u->nano;
167 unsigned long uatto = u->atto;
169 res->sec.x = u->sec.x - v->sec.x;
170 res->nano = unano - v->nano;
171 res->atto = uatto - v->atto;
173 if (res->atto > uatto) {
174 res->atto += 1000000000UL;
175 --res->nano;
178 if (res->nano > unano) {
179 res->nano += 1000000000UL;
180 --res->sec.x;
184 /* XXX: breaks tai encapsulation */
186 /* calcs u + v */
187 static inline void taia_add(struct taia *res,
188 const struct taia *u,
189 const struct taia *v)
191 res->sec.x = u->sec.x + v->sec.x;
192 res->nano = u->nano + v->nano;
193 res->atto = u->atto + v->atto;
195 if (res->atto > 999999999UL) {
196 res->atto -= 1000000000UL;
197 ++res->nano;
200 if (res->nano > 999999999UL) {
201 res->nano -= 1000000000UL;
202 ++res->sec.x;
206 /* 1 if t is less than u, 0 otherwise */
207 static inline int taia_less(const struct taia *t, const struct taia *u)
209 if (t->sec.x < u->sec.x)
210 return 1;
211 if (t->sec.x > u->sec.x)
212 return 0;
213 if (t->nano < u->nano)
214 return 1;
215 if (t->nano > u->nano)
216 return 0;
217 return t->atto < u->atto;
220 static inline int is_good_taia(struct taia *arrival_taia,
221 struct taia *packet_taia)
223 int is_ts_good = 0;
224 struct taia sub_res;
226 if (taia_less(arrival_taia, packet_taia)) {
227 taia_sub(&sub_res, packet_taia, arrival_taia);
228 if (taia_less(&sub_res, &tolerance_taia))
229 is_ts_good = 1;
230 else
231 is_ts_good = 0;
232 } else {
233 taia_sub(&sub_res, arrival_taia, packet_taia);
234 if (taia_less(&sub_res, &tolerance_taia))
235 is_ts_good = 1;
236 else
237 is_ts_good = 0;
240 return is_ts_good;
243 #endif /* CURVE_H */