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.
17 #include "crypto_box_curve25519xsalsa20poly1305.h"
19 /* Some parts derived from public domain code from curveprotect project */
27 uint32_t nano
; /* 0...999999999 */
28 uint32_t atto
; /* 0...999999999 */
31 /* Delay tolerance for packets! */
32 static struct taia tolerance_taia
= {
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
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
;
52 struct curve25519_struct
{
55 unsigned char *enc_buf
;
56 struct spinlock enc_lock
;
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
)
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;
96 static inline void tai_unpack(unsigned char *s
, struct tai
*t
)
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];
111 static inline void taia_pack(unsigned char *s
, struct taia
*t
)
115 tai_pack(s
, &t
->sec
);
118 s
[7] = x
& 255; x
>>= 8;
119 s
[6] = x
& 255; x
>>= 8;
120 s
[5] = x
& 255; x
>>= 8;
123 s
[3] = x
& 255; x
>>= 8;
124 s
[2] = x
& 255; x
>>= 8;
125 s
[1] = x
& 255; x
>>= 8;
129 static inline void taia_unpack(unsigned char *s
, struct taia
*t
)
133 tai_unpack(s
, &t
->sec
);
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];
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];
147 #define tai_unix(t, u) ((void) ((t)->x = 4611686018427387914ULL + (uint64_t) (u)))
149 static inline void taia_now(struct taia
*t
)
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 */
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;
178 if (res
->nano
> unano
) {
179 res
->nano
+= 1000000000UL;
184 /* XXX: breaks tai encapsulation */
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;
200 if (res
->nano
> 999999999UL) {
201 res
->nano
-= 1000000000UL;
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
)
211 if (t
->sec
.x
> u
->sec
.x
)
213 if (t
->nano
< u
->nano
)
215 if (t
->nano
> u
->nano
)
217 return t
->atto
< u
->atto
;
220 static inline int is_good_taia(struct taia
*arrival_taia
,
221 struct taia
*packet_taia
)
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
))
233 taia_sub(&sub_res
, arrival_taia
, packet_taia
);
234 if (taia_less(&sub_res
, &tolerance_taia
))