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>
31 int curve25519_pubkey_hexparse_32(unsigned char *bin
, size_t blen
,
32 const char *ascii
, size_t alen
)
34 int ret
= sscanf(ascii
,
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 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
39 &bin
[0], &bin
[1], &bin
[2], &bin
[3], &bin
[4],
40 &bin
[5], &bin
[6], &bin
[7], &bin
[8], &bin
[9],
41 &bin
[10], &bin
[11], &bin
[12], &bin
[13], &bin
[14],
42 &bin
[15], &bin
[16], &bin
[17], &bin
[18], &bin
[19],
43 &bin
[20], &bin
[21], &bin
[22], &bin
[23], &bin
[24],
44 &bin
[25], &bin
[26], &bin
[27], &bin
[28], &bin
[29],
49 void curve25519_alloc_or_maybe_die(struct curve25519_struct
*curve
)
51 curve
->enc_size
= curve
->dec_size
= TUNBUFF_SIZ
;
53 curve
->enc
= xmalloc_aligned(curve
->enc_size
, 16);
54 curve
->dec
= xmalloc_aligned(curve
->dec_size
, 16);
56 spinlock_init(&curve
->enc_lock
);
57 spinlock_init(&curve
->dec_lock
);
60 void curve25519_free(void *curvep
)
62 struct curve25519_struct
*curve
= curvep
;
64 xzfree(curve
->enc
, curve
->enc_size
);
65 xzfree(curve
->dec
, curve
->dec_size
);
67 spinlock_destroy(&curve
->enc_lock
);
68 spinlock_destroy(&curve
->dec_lock
);
71 void curve25519_proto_init(struct curve25519_proto
*proto
,
72 unsigned char *pubkey_remote
, size_t len
)
76 struct passwd
*pw
= getpwuid(getuid());
77 unsigned char secretkey_own
[crypto_box_sec_key_size
];
78 unsigned char publickey_own
[crypto_box_pub_key_size
];
80 fmemset(secretkey_own
, 0, sizeof(secretkey_own
));
81 fmemset(publickey_own
, 0, sizeof(publickey_own
));
83 if (unlikely(!pubkey_remote
|| len
!= sizeof(publickey_own
)))
84 panic("Invalid argument on curve25519_proto_init!\n");
86 slprintf(file
, sizeof(file
), "%s/%s", pw
->pw_dir
, FILE_PRIVKEY
);
87 read_blob_or_die(file
, secretkey_own
, sizeof(secretkey_own
));
89 crypto_scalarmult_curve25519_base(publickey_own
, secretkey_own
);
90 result
= crypto_verify_32(publickey_own
, pubkey_remote
);
93 panic("Remote end has same public key as you have!\n");
95 crypto_box_beforenm(proto
->key
, pubkey_remote
, secretkey_own
);
97 fmemset(proto
->enonce
, 0, sizeof(proto
->enonce
));
98 fmemset(proto
->dnonce
, 0, sizeof(proto
->dnonce
));
100 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
101 xmemset(publickey_own
, 0, sizeof(publickey_own
));
104 ssize_t
curve25519_encode(struct curve25519_struct
*curve
,
105 struct curve25519_proto
*proto
,
106 unsigned char *plaintext
, size_t size
,
107 unsigned char **ciphertext
)
111 struct taia packet_taia
;
113 spinlock_lock(&curve
->enc_lock
);
114 if (unlikely(size
> curve
->enc_size
)) {
119 taia_now(&packet_taia
);
120 taia_pack(NONCE_EDN_OFFSET(proto
->enonce
), &packet_taia
);
122 fmemset(curve
->enc
, 0, curve
->enc_size
);
123 ret
= crypto_box_afternm(curve
->enc
, plaintext
, size
,
124 proto
->enonce
, proto
->key
);
130 fmemcpy(NONCE_PKT_OFFSET(curve
->enc
),
131 NONCE_EDN_OFFSET(proto
->enonce
), NONCE_LENGTH
);
132 for (i
= 0; i
< NONCE_RND_LENGTH
; ++i
)
133 curve
->enc
[i
] = (uint8_t) secrand();
135 (*ciphertext
) = curve
->enc
;
137 spinlock_unlock(&curve
->enc_lock
);
141 ssize_t
curve25519_decode(struct curve25519_struct
*curve
,
142 struct curve25519_proto
*proto
,
143 unsigned char *ciphertext
, size_t size
,
144 unsigned char **plaintext
,
145 struct taia
*arrival_taia
)
149 struct taia packet_taia
, tmp_taia
;
151 spinlock_lock(&curve
->dec_lock
);
152 if (unlikely(size
> curve
->dec_size
|| size
< NONCE_ALL_LENGTH
)) {
153 done
= size
< NONCE_ALL_LENGTH
? 0 : -ENOMEM
;
157 if (arrival_taia
== NULL
) {
159 arrival_taia
= &tmp_taia
;
162 taia_unpack(NONCE_PKT_OFFSET(ciphertext
), &packet_taia
);
163 if (taia_looks_good(arrival_taia
, &packet_taia
) == 0) {
168 fmemcpy(NONCE_EDN_OFFSET(proto
->dnonce
),
169 NONCE_PKT_OFFSET(ciphertext
), NONCE_LENGTH
);
170 fmemset(curve
->dec
, 0, curve
->dec_size
);
172 ret
= crypto_box_open_afternm(curve
->dec
, ciphertext
, size
,
173 proto
->dnonce
, proto
->key
);
179 (*plaintext
) = curve
->dec
;
181 spinlock_unlock(&curve
->dec_lock
);