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.
16 #include <sys/types.h>
29 #include "crypto_verify_32.h"
30 #include "crypto_box_curve25519xsalsa20poly1305.h"
31 #include "crypto_scalarmult_curve25519.h"
33 /* Some parts derived from public domain code from curveprotect project */
35 #define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm
36 #define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm
37 #define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm
39 #define NONCE_LENGTH 16 /* size of taia */
40 #define NONCE_OFFSET (crypto_box_curve25519xsalsa20poly1305_NONCEBYTES - NONCE_LENGTH)
42 void curve25519_selftest(void)
44 /* Test from the NaCl library */
46 unsigned char alicesk
[32] = {
47 0x77, 0x07, 0x6d, 0x0a, 0x73, 0x18, 0xa5, 0x7d,
48 0x3c, 0x16, 0xc1, 0x72, 0x51, 0xb2, 0x66, 0x45,
49 0xdf, 0x4c, 0x2f, 0x87, 0xeb, 0xc0, 0x99, 0x2a,
50 0xb1, 0x77, 0xfb, 0xa5, 0x1d, 0xb9, 0x2c, 0x2a
52 unsigned char bobpk
[32] = {
53 0xde, 0x9e, 0xdb, 0x7d, 0x7b, 0x7d, 0xc1, 0xb4,
54 0xd3, 0x5b, 0x61, 0xc2, 0xec, 0xe4, 0x35, 0x37,
55 0x3f, 0x83, 0x43, 0xc8, 0x5b, 0x78, 0x67, 0x4d,
56 0xad, 0xfc, 0x7e, 0x14, 0x6f, 0x88, 0x2b, 0x4f
58 unsigned char nonce
[24] = {
59 0x69, 0x69, 0x6e, 0xe9, 0x55, 0xb6, 0x2b, 0x73,
60 0xcd, 0x62, 0xbd, 0xa8, 0x75, 0xfc, 0x73, 0xd6,
61 0x82, 0x19, 0xe0, 0x03, 0x6b, 0x7a, 0x0b, 0x37
63 /* API requires first 32 bytes to be 0 */
64 unsigned char m
[163] = {
65 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
66 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
67 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
68 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
69 0xbe, 0x07, 0x5f, 0xc5, 0x3c, 0x81, 0xf2, 0xd5,
70 0xcf, 0x14, 0x13, 0x16, 0xeb, 0xeb, 0x0c, 0x7b,
71 0x52, 0x28, 0xc5, 0x2a, 0x4c, 0x62, 0xcb, 0xd4,
72 0x4b, 0x66, 0x84, 0x9b, 0x64, 0x24, 0x4f, 0xfc,
73 0xe5, 0xec, 0xba, 0xaf, 0x33, 0xbd, 0x75, 0x1a,
74 0x1a, 0xc7, 0x28, 0xd4, 0x5e, 0x6c, 0x61, 0x29,
75 0x6c, 0xdc, 0x3c, 0x01, 0x23, 0x35, 0x61, 0xf4,
76 0x1d, 0xb6, 0x6c, 0xce, 0x31, 0x4a, 0xdb, 0x31,
77 0x0e, 0x3b, 0xe8, 0x25, 0x0c, 0x46, 0xf0, 0x6d,
78 0xce, 0xea, 0x3a, 0x7f, 0xa1, 0x34, 0x80, 0x57,
79 0xe2, 0xf6, 0x55, 0x6a, 0xd6, 0xb1, 0x31, 0x8a,
80 0x02, 0x4a, 0x83, 0x8f, 0x21, 0xaf, 0x1f, 0xde,
81 0x04, 0x89, 0x77, 0xeb, 0x48, 0xf5, 0x9f, 0xfd,
82 0x49, 0x24, 0xca, 0x1c, 0x60, 0x90, 0x2e, 0x52,
83 0xf0, 0xa0, 0x89, 0xbc, 0x76, 0x89, 0x70, 0x40,
84 0xe0, 0x82, 0xf9, 0x37, 0x76, 0x38, 0x48, 0x64,
88 unsigned char result
[147] = {
89 0xf3, 0xff, 0xc7, 0x70, 0x3f, 0x94, 0x00, 0xe5,
90 0x2a, 0x7d, 0xfb, 0x4b, 0x3d, 0x33, 0x05, 0xd9,
91 0x8e, 0x99, 0x3b, 0x9f, 0x48, 0x68, 0x12, 0x73,
92 0xc2, 0x96, 0x50, 0xba, 0x32, 0xfc, 0x76, 0xce,
93 0x48, 0x33, 0x2e, 0xa7, 0x16, 0x4d, 0x96, 0xa4,
94 0x47, 0x6f, 0xb8, 0xc5, 0x31, 0xa1, 0x18, 0x6a,
95 0xc0, 0xdf, 0xc1, 0x7c, 0x98, 0xdc, 0xe8, 0x7b,
96 0x4d, 0xa7, 0xf0, 0x11, 0xec, 0x48, 0xc9, 0x72,
97 0x71, 0xd2, 0xc2, 0x0f, 0x9b, 0x92, 0x8f, 0xe2,
98 0x27, 0x0d, 0x6f, 0xb8, 0x63, 0xd5, 0x17, 0x38,
99 0xb4, 0x8e, 0xee, 0xe3, 0x14, 0xa7, 0xcc, 0x8a,
100 0xb9, 0x32, 0x16, 0x45, 0x48, 0xe5, 0x26, 0xae,
101 0x90, 0x22, 0x43, 0x68, 0x51, 0x7a, 0xcf, 0xea,
102 0xbd, 0x6b, 0xb3, 0x73, 0x2b, 0xc0, 0xe9, 0xda,
103 0x99, 0x83, 0x2b, 0x61, 0xca, 0x01, 0xb6, 0xde,
104 0x56, 0x24, 0x4a, 0x9e, 0x88, 0xd5, 0xf9, 0xb3,
105 0x79, 0x73, 0xf6, 0x22, 0xa4, 0x3d, 0x14, 0xa6,
106 0x59, 0x9b, 0x1f, 0x65, 0x4c, 0xb4, 0x5a, 0x74,
110 crypto_box_curve25519xsalsa20poly1305(c
, m
, 163, nonce
, bobpk
, alicesk
);
112 for (i
= 16; i
< 163; ++i
) {
113 if (c
[i
] != result
[i
- 16])
114 panic("PANIC: crypto selftest failed at pos %d "
115 "(%u != %u)! :-(\n", i
, c
[i
], result
[i
]);
119 static int hexdigit(char x
)
121 if (x
>= '0' && x
<= '9')
123 if (x
>= 'a' && x
<= 'f')
124 return 10 + (x
- 'a');
125 if (x
>= 'A' && x
<= 'F')
126 return 10 + (x
- 'A');
130 int curve25519_pubkey_hexparse_32(unsigned char *y
, size_t ylen
,
131 const char *x
, size_t len
)
133 int seen_digits
= 0, seen_colons
= 0;
135 if (!x
|| !y
|| ylen
!= 32)
138 while (len
> 0 && seen_digits
!= 32) {
150 digit0
= hexdigit(x
[0]);
154 digit1
= hexdigit(x
[1]);
158 *y
++ = digit1
+ 16 * digit0
;
165 if (/*x[0] != '\0' ||*/ seen_digits
!= 32 || seen_colons
!= 31)
171 int curve25519_alloc_or_maybe_die(struct curve25519_struct
*c
)
176 c
->enc_buf_size
= TUNBUFF_SIZ
;
177 c
->dec_buf_size
= TUNBUFF_SIZ
;
179 c
->enc_buf
= xmalloc_aligned(c
->enc_buf_size
, 16);
180 c
->dec_buf
= xmalloc_aligned(c
->dec_buf_size
, 16);
182 spinlock_init(&c
->enc_lock
);
183 spinlock_init(&c
->dec_lock
);
185 mt_init_by_seed_rand_array();
190 void curve25519_free(void *vc
)
192 struct curve25519_struct
*c
= vc
;
197 memset(c
->enc_buf
, 0, c
->enc_buf_size
);
198 memset(c
->dec_buf
, 0, c
->dec_buf_size
);
203 spinlock_destroy(&c
->enc_lock
);
204 spinlock_destroy(&c
->dec_lock
);
207 int curve25519_proto_init(struct curve25519_proto
*p
, unsigned char *pubkey_remote
,
208 size_t len
, char *home
, int server
)
213 unsigned char secretkey_own
[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
] = { 0 };
214 unsigned char publickey_own
[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
] = { 0 };
216 if (!pubkey_remote
||
217 len
!= crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
)
220 memset(path
, 0, sizeof(path
));
221 slprintf(path
, sizeof(path
), "%s/%s", home
, FILE_PRIVKEY
);
223 fd
= open_or_die(path
, O_RDONLY
);
225 ret
= read(fd
, secretkey_own
, sizeof(secretkey_own
));
226 if (ret
!= sizeof(secretkey_own
)) {
227 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
228 panic("Cannot read private key!\n");
233 crypto_scalarmult_curve25519_base(publickey_own
, secretkey_own
);
235 if (!crypto_verify_32(publickey_own
, pubkey_remote
)) {
236 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
237 xmemset(publickey_own
, 0, sizeof(publickey_own
));
238 panic("PANIC: remote end has same public key as you have!!!\n");
241 crypto_box_beforenm(p
->key
, pubkey_remote
, secretkey_own
);
243 xmemset(p
->enonce
, 0, sizeof(p
->enonce
));
244 xmemset(p
->dnonce
, 0, sizeof(p
->dnonce
));
246 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
247 xmemset(publickey_own
, 0, sizeof(publickey_own
));
252 ssize_t
curve25519_encode(struct curve25519_struct
*c
, struct curve25519_proto
*p
,
253 unsigned char *plaintext
, size_t size
,
254 unsigned char **chipertext
)
258 struct taia packet_taia
;
260 spinlock_lock(&c
->enc_lock
);
262 if (unlikely(size
> c
->enc_buf_size
)) {
263 spinlock_unlock(&c
->enc_lock
);
267 taia_now(&packet_taia
);
268 taia_pack(p
->enonce
+ NONCE_OFFSET
, &packet_taia
);
270 memset(c
->enc_buf
, 0, c
->enc_buf_size
);
272 ret
= crypto_box_afternm(c
->enc_buf
, plaintext
, size
,
275 spinlock_unlock(&c
->enc_lock
);
279 memcpy(c
->enc_buf
+ crypto_box_boxzerobytes
- NONCE_LENGTH
,
280 p
->enonce
+ NONCE_OFFSET
, NONCE_LENGTH
);
282 for (i
= 0; i
< crypto_box_boxzerobytes
- NONCE_LENGTH
; ++i
)
283 c
->enc_buf
[i
] = (uint8_t) mt_rand_int32();
285 (*chipertext
) = c
->enc_buf
;
287 spinlock_unlock(&c
->enc_lock
);
292 ssize_t
curve25519_decode(struct curve25519_struct
*c
, struct curve25519_proto
*p
,
293 unsigned char *chipertext
, size_t size
,
294 unsigned char **plaintext
, struct taia
*arrival_taia
)
298 struct taia packet_taia
, __arrival_taia
;
300 spinlock_lock(&c
->dec_lock
);
302 if (unlikely(size
> c
->dec_buf_size
)) {
303 spinlock_unlock(&c
->dec_lock
);
307 if (unlikely(size
< crypto_box_boxzerobytes
+ NONCE_LENGTH
)) {
308 spinlock_unlock(&c
->dec_lock
);
311 if (arrival_taia
== NULL
) {
312 taia_now(&__arrival_taia
);
313 arrival_taia
= &__arrival_taia
;
316 taia_unpack(chipertext
+ crypto_box_boxzerobytes
- NONCE_LENGTH
,
318 if (is_good_taia(arrival_taia
, &packet_taia
) == 0) {
319 /* Ignoring packet */
320 spinlock_unlock(&c
->dec_lock
);
321 syslog(LOG_ERR
, "Bad packet time! Dropping connection!\n");
325 memcpy(p
->dnonce
+ NONCE_OFFSET
,
326 chipertext
+ crypto_box_boxzerobytes
- NONCE_LENGTH
,
329 memset(c
->dec_buf
, 0, c
->dec_buf_size
);
331 ret
= crypto_box_open_afternm(c
->dec_buf
, chipertext
, size
,
334 spinlock_unlock(&c
->dec_lock
);
338 (*plaintext
) = c
->dec_buf
;
340 spinlock_unlock(&c
->dec_lock
);