2 * netsniff-ng - the packet sniffing beast
3 * By Daniel Borkmann <daniel@netsniff-ng.org>
4 * Copyright 2011 - 2013 Daniel Borkmann.
5 * Subject to the GPL, version 2.
17 #include "crypto_box_curve25519xsalsa20poly1305.h"
29 static struct taia tolerance_taia
= {
35 #define crypto_box_zerobytes crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
36 #define crypto_box_boxzerobytes crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
38 #define crypto_box_noncebytes crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
39 #define crypto_box_beforenmbytes crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
41 struct curve25519_proto
{
42 unsigned char enonce
[crypto_box_noncebytes
] __aligned_16
;
43 unsigned char dnonce
[crypto_box_noncebytes
] __aligned_16
;
44 unsigned char key
[crypto_box_noncebytes
] __aligned_16
;
47 struct curve25519_struct
{
48 unsigned char *enc_buf
;
49 unsigned char *dec_buf
;
52 struct spinlock enc_lock
;
53 struct spinlock dec_lock
;
56 extern void curve25519_selftest(void);
57 extern void curve25519_alloc_or_maybe_die(struct curve25519_struct
*curve
);
58 extern void curve25519_free(void *curve
);
59 extern int curve25519_pubkey_hexparse_32(unsigned char *bin
, size_t blen
, const char *ascii
, size_t alen
);
60 extern int curve25519_proto_init(struct curve25519_proto
*proto
, unsigned char *pubkey_remote
, size_t len
,
61 char *home
, int server
);
62 extern ssize_t
curve25519_encode(struct curve25519_struct
*curve
, struct curve25519_proto
*proto
,
63 unsigned char *plaintext
, size_t size
, unsigned char **chipertext
);
64 extern ssize_t
curve25519_decode(struct curve25519_struct
*curve
, struct curve25519_proto
*proto
,
65 unsigned char *chipertext
, size_t size
, unsigned char **plaintext
,
66 struct taia
*arrival_taia
);
68 static inline void tai_pack(unsigned char *s
, struct tai
*t
)
73 s
[7] = x
& 255; x
>>= 8;
74 s
[6] = x
& 255; x
>>= 8;
75 s
[5] = x
& 255; x
>>= 8;
76 s
[4] = x
& 255; x
>>= 8;
77 s
[3] = x
& 255; x
>>= 8;
78 s
[2] = x
& 255; x
>>= 8;
79 s
[1] = x
& 255; x
>>= 8;
83 static inline void tai_unpack(unsigned char *s
, struct tai
*t
)
87 x
= (unsigned char) s
[0];
88 x
<<= 8; x
+= (unsigned char) s
[1];
89 x
<<= 8; x
+= (unsigned char) s
[2];
90 x
<<= 8; x
+= (unsigned char) s
[3];
91 x
<<= 8; x
+= (unsigned char) s
[4];
92 x
<<= 8; x
+= (unsigned char) s
[5];
93 x
<<= 8; x
+= (unsigned char) s
[6];
94 x
<<= 8; x
+= (unsigned char) s
[7];
98 static inline void taia_pack(unsigned char *s
, struct taia
*t
)
102 tai_pack(s
, &t
->sec
);
105 s
[7] = x
& 255; x
>>= 8;
106 s
[6] = x
& 255; x
>>= 8;
107 s
[5] = x
& 255; x
>>= 8;
110 s
[3] = x
& 255; x
>>= 8;
111 s
[2] = x
& 255; x
>>= 8;
112 s
[1] = x
& 255; x
>>= 8;
116 static inline void taia_unpack(unsigned char *s
, struct taia
*t
)
120 tai_unpack(s
, &t
->sec
);
122 x
= (unsigned char) s
[4];
123 x
<<= 8; x
+= (unsigned char) s
[5];
124 x
<<= 8; x
+= (unsigned char) s
[6];
125 x
<<= 8; x
+= (unsigned char) s
[7];
127 x
= (unsigned char) s
[0];
128 x
<<= 8; x
+= (unsigned char) s
[1];
129 x
<<= 8; x
+= (unsigned char) s
[2];
130 x
<<= 8; x
+= (unsigned char) s
[3];
134 #define tai_unix(t, u) ((void) ((t)->x = 4611686018427387914ULL + (uint64_t) (u)))
136 static inline void taia_now(struct taia
*t
)
140 gettimeofday(&now
, NULL
);
142 tai_unix(&t
->sec
, now
.tv_sec
);
143 t
->nano
= 1000 * now
.tv_usec
+ 500;
147 static inline void taia_sub(struct taia
*res
, const struct taia
*u
, const struct taia
*v
)
149 unsigned long unano
= u
->nano
;
150 unsigned long uatto
= u
->atto
;
152 res
->sec
.x
= u
->sec
.x
- v
->sec
.x
;
153 res
->nano
= unano
- v
->nano
;
154 res
->atto
= uatto
- v
->atto
;
156 if (res
->atto
> uatto
) {
157 res
->atto
+= 1000000000UL;
161 if (res
->nano
> unano
) {
162 res
->nano
+= 1000000000UL;
167 static inline void taia_add(struct taia
*res
, const struct taia
*u
, const struct taia
*v
)
169 res
->sec
.x
= u
->sec
.x
+ v
->sec
.x
;
170 res
->nano
= u
->nano
+ v
->nano
;
171 res
->atto
= u
->atto
+ v
->atto
;
173 if (res
->atto
> 999999999UL) {
174 res
->atto
-= 1000000000UL;
178 if (res
->nano
> 999999999UL) {
179 res
->nano
-= 1000000000UL;
184 static inline int taia_less(const struct taia
*t
, const struct taia
*u
)
186 if (t
->sec
.x
< u
->sec
.x
)
188 if (t
->sec
.x
> u
->sec
.x
)
190 if (t
->nano
< u
->nano
)
192 if (t
->nano
> u
->nano
)
194 return t
->atto
< u
->atto
;
197 static inline int is_good_taia(struct taia
*arrival_taia
, struct taia
*packet_taia
)
202 if (taia_less(arrival_taia
, packet_taia
)) {
203 taia_sub(&sub_res
, packet_taia
, arrival_taia
);
204 if (taia_less(&sub_res
, &tolerance_taia
))
209 taia_sub(&sub_res
, arrival_taia
, packet_taia
);
210 if (taia_less(&sub_res
, &tolerance_taia
))