2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 - 2013 Daniel Borkmann.
4 * Subject to the GPL, version 2.
15 #include <sys/types.h>
30 int curve25519_pubkey_hexparse_32(unsigned char *bin
, size_t blen
,
31 const char *ascii
, size_t alen
)
33 int ret
= sscanf(ascii
,
34 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
35 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
36 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
37 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
38 &bin
[0], &bin
[1], &bin
[2], &bin
[3], &bin
[4],
39 &bin
[5], &bin
[6], &bin
[7], &bin
[8], &bin
[9],
40 &bin
[10], &bin
[11], &bin
[12], &bin
[13], &bin
[14],
41 &bin
[15], &bin
[16], &bin
[17], &bin
[18], &bin
[19],
42 &bin
[20], &bin
[21], &bin
[22], &bin
[23], &bin
[24],
43 &bin
[25], &bin
[26], &bin
[27], &bin
[28], &bin
[29],
48 void curve25519_alloc_or_maybe_die(struct curve25519_struct
*curve
)
50 curve
->enc_buf_size
= curve
->dec_buf_size
= TUNBUFF_SIZ
;
52 curve
->enc_buf
= xmalloc_aligned(curve
->enc_buf_size
, 16);
53 curve
->dec_buf
= xmalloc_aligned(curve
->dec_buf_size
, 16);
55 spinlock_init(&curve
->enc_lock
);
56 spinlock_init(&curve
->dec_lock
);
59 void curve25519_free(void *curvep
)
61 struct curve25519_struct
*curve
= curvep
;
63 memset(curve
->enc_buf
, 0, curve
->enc_buf_size
);
64 memset(curve
->dec_buf
, 0, curve
->dec_buf_size
);
66 xfree(curve
->enc_buf
);
67 xfree(curve
->dec_buf
);
69 spinlock_destroy(&curve
->enc_lock
);
70 spinlock_destroy(&curve
->dec_lock
);
73 int curve25519_proto_init(struct curve25519_proto
*proto
, unsigned char *pubkey_remote
,
74 size_t len
, char *home
, int server
)
79 unsigned char secretkey_own
[crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
];
80 unsigned char publickey_own
[crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
];
82 fmemset(secretkey_own
, 0, sizeof(secretkey_own
));
83 fmemset(publickey_own
, 0, sizeof(publickey_own
));
85 if (!pubkey_remote
|| len
!= sizeof(publickey_own
))
88 slprintf(path
, sizeof(path
), "%s/%s", home
, FILE_PRIVKEY
);
89 fd
= open_or_die(path
, O_RDONLY
);
91 ret
= read(fd
, secretkey_own
, sizeof(secretkey_own
));
92 if (ret
!= sizeof(secretkey_own
)) {
93 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
94 panic("Cannot read private key!\n");
99 crypto_scalarmult_curve25519_base(publickey_own
, secretkey_own
);
101 if (!crypto_verify_32(publickey_own
, pubkey_remote
)) {
102 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
103 xmemset(publickey_own
, 0, sizeof(publickey_own
));
104 panic("PANIC: remote end has same public key as you have!!!\n");
107 crypto_box_beforenm(proto
->key
, pubkey_remote
, secretkey_own
);
109 xmemset(proto
->enonce
, 0, sizeof(proto
->enonce
));
110 xmemset(proto
->dnonce
, 0, sizeof(proto
->dnonce
));
112 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
113 xmemset(publickey_own
, 0, sizeof(publickey_own
));
118 ssize_t
curve25519_encode(struct curve25519_struct
*curve
, struct curve25519_proto
*proto
,
119 unsigned char *plaintext
, size_t size
, unsigned char **chipertext
)
123 struct taia packet_taia
;
125 spinlock_lock(&curve
->enc_lock
);
127 if (unlikely(size
> curve
->enc_buf_size
)) {
132 taia_now(&packet_taia
);
133 taia_pack(proto
->enonce
+ NONCE_OFFSET
, &packet_taia
);
135 memset(curve
->enc_buf
, 0, curve
->enc_buf_size
);
136 ret
= crypto_box_afternm(curve
->enc_buf
, plaintext
, size
, proto
->enonce
, proto
->key
);
142 fmemcpy(curve
->enc_buf
+ crypto_box_boxzerobytes
- NONCE_LENGTH
,
143 proto
->enonce
+ NONCE_OFFSET
, NONCE_LENGTH
);
145 for (i
= 0; i
< crypto_box_boxzerobytes
- NONCE_LENGTH
; ++i
)
146 curve
->enc_buf
[i
] = (uint8_t) secrand();
148 (*chipertext
) = curve
->enc_buf
;
150 spinlock_unlock(&curve
->enc_lock
);
154 ssize_t
curve25519_decode(struct curve25519_struct
*curve
, struct curve25519_proto
*proto
,
155 unsigned char *chipertext
, size_t size
, unsigned char **plaintext
,
156 struct taia
*arrival_taia
)
160 struct taia packet_taia
, arrival_taia2
;
162 spinlock_lock(&curve
->dec_lock
);
164 if (unlikely(size
> curve
->dec_buf_size
)) {
168 if (unlikely(size
< crypto_box_boxzerobytes
+ NONCE_LENGTH
)) {
172 if (arrival_taia
== NULL
) {
173 taia_now(&arrival_taia2
);
174 arrival_taia
= &arrival_taia2
;
177 taia_unpack(chipertext
+ crypto_box_boxzerobytes
- NONCE_LENGTH
, &packet_taia
);
178 if (taia_looks_good(arrival_taia
, &packet_taia
) == 0) {
179 syslog(LOG_ERR
, "Bad packet time! Dropping connection!\n");
184 memcpy(proto
->dnonce
+ NONCE_OFFSET
, chipertext
+ crypto_box_boxzerobytes
- NONCE_LENGTH
, NONCE_LENGTH
);
185 memset(curve
->dec_buf
, 0, curve
->dec_buf_size
);
187 ret
= crypto_box_open_afternm(curve
->dec_buf
, chipertext
, size
, proto
->dnonce
, proto
->key
);
193 (*plaintext
) = curve
->dec_buf
;
195 spinlock_unlock(&curve
->dec_lock
);