2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 - 2013 Daniel Borkmann.
4 * Subject to the GPL, version 2.
16 #include <sys/types.h>
32 int curve25519_pubkey_hexparse_32(unsigned char *bin
, size_t blen
,
33 const char *ascii
, size_t alen
)
35 int ret
= sscanf(ascii
,
36 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
37 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
38 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
39 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
40 &bin
[0], &bin
[1], &bin
[2], &bin
[3], &bin
[4],
41 &bin
[5], &bin
[6], &bin
[7], &bin
[8], &bin
[9],
42 &bin
[10], &bin
[11], &bin
[12], &bin
[13], &bin
[14],
43 &bin
[15], &bin
[16], &bin
[17], &bin
[18], &bin
[19],
44 &bin
[20], &bin
[21], &bin
[22], &bin
[23], &bin
[24],
45 &bin
[25], &bin
[26], &bin
[27], &bin
[28], &bin
[29],
50 void curve25519_alloc_or_maybe_die(struct curve25519_struct
*curve
)
52 curve
->enc_size
= curve
->dec_size
= TUNBUFF_SIZ
;
54 curve
->enc
= xmalloc_aligned(curve
->enc_size
, 16);
55 curve
->dec
= xmalloc_aligned(curve
->dec_size
, 16);
57 spinlock_init(&curve
->enc_lock
);
58 spinlock_init(&curve
->dec_lock
);
61 void curve25519_free(void *curvep
)
63 struct curve25519_struct
*curve
= curvep
;
65 xzfree(curve
->enc
, curve
->enc_size
);
66 xzfree(curve
->dec
, curve
->dec_size
);
68 spinlock_destroy(&curve
->enc_lock
);
69 spinlock_destroy(&curve
->dec_lock
);
72 void curve25519_proto_init(struct curve25519_proto
*proto
,
73 unsigned char *pubkey_remote
, size_t len
)
77 struct passwd
*pw
= getpwuid(getuid());
78 unsigned char secretkey_own
[crypto_box_sec_key_size
];
79 unsigned char publickey_own
[crypto_box_pub_key_size
];
81 fmemset(secretkey_own
, 0, sizeof(secretkey_own
));
82 fmemset(publickey_own
, 0, sizeof(publickey_own
));
84 if (unlikely(!pubkey_remote
|| len
!= sizeof(publickey_own
)))
85 panic("Invalid argument on curve25519_proto_init!\n");
87 slprintf(file
, sizeof(file
), "%s/%s", pw
->pw_dir
, FILE_PRIVKEY
);
88 read_blob_or_die(file
, secretkey_own
, sizeof(secretkey_own
));
90 crypto_scalarmult_curve25519_base(publickey_own
, secretkey_own
);
91 result
= crypto_verify_32(publickey_own
, pubkey_remote
);
94 panic("Remote end has same public key as you have!\n");
96 crypto_box_beforenm(proto
->key
, pubkey_remote
, secretkey_own
);
98 fmemset(proto
->enonce
, 0, sizeof(proto
->enonce
));
99 fmemset(proto
->dnonce
, 0, sizeof(proto
->dnonce
));
101 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
102 xmemset(publickey_own
, 0, sizeof(publickey_own
));
105 ssize_t
curve25519_encode(struct curve25519_struct
*curve
,
106 struct curve25519_proto
*proto
,
107 unsigned char *plaintext
, size_t size
,
108 unsigned char **ciphertext
)
112 struct taia packet_taia
;
114 spinlock_lock(&curve
->enc_lock
);
115 if (unlikely(size
> curve
->enc_size
)) {
120 taia_now(&packet_taia
);
121 taia_pack(NONCE_EDN_OFFSET(proto
->enonce
), &packet_taia
);
123 fmemset(curve
->enc
, 0, curve
->enc_size
);
124 ret
= crypto_box_afternm(curve
->enc
, plaintext
, size
,
125 proto
->enonce
, proto
->key
);
131 fmemcpy(NONCE_PKT_OFFSET(curve
->enc
),
132 NONCE_EDN_OFFSET(proto
->enonce
), NONCE_LENGTH
);
133 for (i
= 0; i
< NONCE_RND_LENGTH
; ++i
)
134 curve
->enc
[i
] = (uint8_t) secrand();
136 (*ciphertext
) = curve
->enc
;
138 spinlock_unlock(&curve
->enc_lock
);
142 ssize_t
curve25519_decode(struct curve25519_struct
*curve
,
143 struct curve25519_proto
*proto
,
144 unsigned char *ciphertext
, size_t size
,
145 unsigned char **plaintext
,
146 struct taia
*arrival_taia
)
150 struct taia packet_taia
, tmp_taia
;
152 spinlock_lock(&curve
->dec_lock
);
153 if (unlikely(size
> curve
->dec_size
|| size
< NONCE_ALL_LENGTH
)) {
154 done
= size
< NONCE_ALL_LENGTH
? 0 : -ENOMEM
;
158 if (arrival_taia
== NULL
) {
160 arrival_taia
= &tmp_taia
;
163 taia_unpack(NONCE_PKT_OFFSET(ciphertext
), &packet_taia
);
164 if (taia_looks_good(arrival_taia
, &packet_taia
) == 0) {
169 fmemcpy(NONCE_EDN_OFFSET(proto
->dnonce
),
170 NONCE_PKT_OFFSET(ciphertext
), NONCE_LENGTH
);
171 fmemset(curve
->dec
, 0, curve
->dec_size
);
173 ret
= crypto_box_open_afternm(curve
->dec
, ciphertext
, size
,
174 proto
->dnonce
, proto
->key
);
180 (*plaintext
) = curve
->dec
;
182 spinlock_unlock(&curve
->dec_lock
);