Merge pull request #59 from electronjoe/graceful-SIGTERM-handling
[netsniff-ng-old.git] / curve.h
blob85c6e61ef6a9535f975b0ac0c04942dfcfca7b38
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 - 2013 Daniel Borkmann.
4 * Subject to the GPL, version 2.
5 */
7 #ifndef CURVE_H
8 #define CURVE_H
10 #include <stdint.h>
11 #include <sys/time.h>
13 #include "locking.h"
14 #include "built_in.h"
15 #include "xio.h"
16 #include "crypto_box_curve25519xsalsa20poly1305.h"
18 struct tai {
19 uint64_t x;
22 struct taia {
23 struct tai sec;
24 uint32_t nano;
25 uint32_t atto;
28 static struct taia tolerance_taia = {
29 .sec.x = 0,
30 .nano = 700000000ULL,
31 .atto = 0,
34 #define crypto_box_zerobytes crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
35 #define crypto_box_boxzerobytes crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
37 #define crypto_box_noncebytes crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
38 #define crypto_box_beforenmbytes crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
40 struct curve25519_proto {
41 unsigned char enonce[crypto_box_noncebytes] __aligned_16;
42 unsigned char dnonce[crypto_box_noncebytes] __aligned_16;
43 unsigned char key[crypto_box_noncebytes] __aligned_16;
46 struct curve25519_struct {
47 unsigned char *enc_buf;
48 unsigned char *dec_buf;
49 size_t enc_buf_size;
50 size_t dec_buf_size;
51 struct spinlock enc_lock;
52 struct spinlock dec_lock;
55 extern void curve25519_selftest(void);
56 extern void curve25519_alloc_or_maybe_die(struct curve25519_struct *curve);
57 extern void curve25519_free(void *curve);
58 extern int curve25519_pubkey_hexparse_32(unsigned char *bin, size_t blen, const char *ascii, size_t alen);
59 extern int curve25519_proto_init(struct curve25519_proto *proto, unsigned char *pubkey_remote, size_t len,
60 char *home, int server);
61 extern ssize_t curve25519_encode(struct curve25519_struct *curve, struct curve25519_proto *proto,
62 unsigned char *plaintext, size_t size, unsigned char **chipertext);
63 extern ssize_t curve25519_decode(struct curve25519_struct *curve, struct curve25519_proto *proto,
64 unsigned char *chipertext, size_t size, unsigned char **plaintext,
65 struct taia *arrival_taia);
67 static inline void tai_pack(unsigned char *s, struct tai *t)
69 uint64_t x;
71 x = t->x;
72 s[7] = x & 255; x >>= 8;
73 s[6] = x & 255; x >>= 8;
74 s[5] = x & 255; x >>= 8;
75 s[4] = x & 255; x >>= 8;
76 s[3] = x & 255; x >>= 8;
77 s[2] = x & 255; x >>= 8;
78 s[1] = x & 255; x >>= 8;
79 s[0] = x;
82 static inline void tai_unpack(unsigned char *s, struct tai *t)
84 uint64_t x;
86 x = (unsigned char) s[0];
87 x <<= 8; x += (unsigned char) s[1];
88 x <<= 8; x += (unsigned char) s[2];
89 x <<= 8; x += (unsigned char) s[3];
90 x <<= 8; x += (unsigned char) s[4];
91 x <<= 8; x += (unsigned char) s[5];
92 x <<= 8; x += (unsigned char) s[6];
93 x <<= 8; x += (unsigned char) s[7];
94 t->x = x;
97 static inline void taia_pack(unsigned char *s, struct taia *t)
99 unsigned long x;
101 tai_pack(s, &t->sec);
102 s += 8;
103 x = t->atto;
104 s[7] = x & 255; x >>= 8;
105 s[6] = x & 255; x >>= 8;
106 s[5] = x & 255; x >>= 8;
107 s[4] = x;
108 x = t->nano;
109 s[3] = x & 255; x >>= 8;
110 s[2] = x & 255; x >>= 8;
111 s[1] = x & 255; x >>= 8;
112 s[0] = x;
115 static inline void taia_unpack(unsigned char *s, struct taia *t)
117 unsigned long x;
119 tai_unpack(s, &t->sec);
120 s += 8;
121 x = (unsigned char) s[4];
122 x <<= 8; x += (unsigned char) s[5];
123 x <<= 8; x += (unsigned char) s[6];
124 x <<= 8; x += (unsigned char) s[7];
125 t->atto = x;
126 x = (unsigned char) s[0];
127 x <<= 8; x += (unsigned char) s[1];
128 x <<= 8; x += (unsigned char) s[2];
129 x <<= 8; x += (unsigned char) s[3];
130 t->nano = x;
133 #define tai_unix(t, u) ((void) ((t)->x = 4611686018427387914ULL + (uint64_t) (u)))
135 static inline void taia_now(struct taia *t)
137 struct timeval now;
139 gettimeofday(&now, NULL);
141 tai_unix(&t->sec, now.tv_sec);
142 t->nano = 1000 * now.tv_usec + 500;
143 t->atto = secrand();
146 static inline void taia_sub(struct taia *res, const struct taia *u, const struct taia *v)
148 unsigned long unano = u->nano;
149 unsigned long uatto = u->atto;
151 res->sec.x = u->sec.x - v->sec.x;
152 res->nano = unano - v->nano;
153 res->atto = uatto - v->atto;
155 if (res->atto > uatto) {
156 res->atto += 1000000000UL;
157 --res->nano;
160 if (res->nano > unano) {
161 res->nano += 1000000000UL;
162 --res->sec.x;
166 static inline void taia_add(struct taia *res, const struct taia *u, const struct taia *v)
168 res->sec.x = u->sec.x + v->sec.x;
169 res->nano = u->nano + v->nano;
170 res->atto = u->atto + v->atto;
172 if (res->atto > 999999999UL) {
173 res->atto -= 1000000000UL;
174 ++res->nano;
177 if (res->nano > 999999999UL) {
178 res->nano -= 1000000000UL;
179 ++res->sec.x;
183 static inline int taia_less(const struct taia *t, const struct taia *u)
185 if (t->sec.x < u->sec.x)
186 return 1;
187 if (t->sec.x > u->sec.x)
188 return 0;
189 if (t->nano < u->nano)
190 return 1;
191 if (t->nano > u->nano)
192 return 0;
193 return t->atto < u->atto;
196 static inline int is_good_taia(struct taia *arrival_taia, struct taia *packet_taia)
198 int is_ts_good = 0;
199 struct taia sub_res;
201 if (taia_less(arrival_taia, packet_taia)) {
202 taia_sub(&sub_res, packet_taia, arrival_taia);
203 if (taia_less(&sub_res, &tolerance_taia))
204 is_ts_good = 1;
205 else
206 is_ts_good = 0;
207 } else {
208 taia_sub(&sub_res, arrival_taia, packet_taia);
209 if (taia_less(&sub_res, &tolerance_taia))
210 is_ts_good = 1;
211 else
212 is_ts_good = 0;
215 return is_ts_good;
218 #endif /* CURVE_H */