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 static void curve25519_init(struct curve25519_struct
*curve
)
34 curve
->enc_size
= curve
->dec_size
= TUNBUFF_SIZ
;
36 curve
->enc
= xmalloc_aligned(curve
->enc_size
, 16);
37 curve
->dec
= xmalloc_aligned(curve
->dec_size
, 16);
39 spinlock_init(&curve
->enc_lock
);
40 spinlock_init(&curve
->dec_lock
);
43 static void curve25519_destroy(struct curve25519_struct
*curve
)
45 spinlock_destroy(&curve
->enc_lock
);
46 spinlock_destroy(&curve
->dec_lock
);
48 xzfree(curve
->enc
, curve
->enc_size
);
49 xzfree(curve
->dec
, curve
->dec_size
);
52 struct curve25519_struct
*curve25519_tfm_alloc(void)
54 struct curve25519_struct
*tfm
;
56 tfm
= xzmalloc_aligned(sizeof(*tfm
), 16);
62 void curve25519_tfm_free(struct curve25519_struct
*tfm
)
64 curve25519_destroy(tfm
);
65 xzfree(tfm
, sizeof(*tfm
));
68 void curve25519_tfm_free_void(void *tfm
)
70 curve25519_tfm_free(tfm
);
73 void curve25519_proto_init(struct curve25519_proto
*proto
,
74 unsigned char *pubkey_remote
, size_t len
)
78 struct passwd
*pw
= getpwuid(getuid());
79 unsigned char secretkey_own
[crypto_box_sec_key_size
];
80 unsigned char publickey_own
[crypto_box_pub_key_size
];
82 fmemset(secretkey_own
, 0, sizeof(secretkey_own
));
83 fmemset(publickey_own
, 0, sizeof(publickey_own
));
85 if (unlikely(!pubkey_remote
|| len
!= sizeof(publickey_own
)))
86 panic("Invalid argument on curve25519_proto_init!\n");
88 slprintf(file
, sizeof(file
), "%s/%s", pw
->pw_dir
, FILE_PRIVKEY
);
89 read_blob_or_die(file
, secretkey_own
, sizeof(secretkey_own
));
91 crypto_scalarmult_curve25519_base(publickey_own
, secretkey_own
);
92 result
= crypto_verify_32(publickey_own
, pubkey_remote
);
95 panic("Remote end has same public key as you have!\n");
97 crypto_box_beforenm(proto
->key
, pubkey_remote
, secretkey_own
);
99 fmemset(proto
->enonce
, 0, sizeof(proto
->enonce
));
100 fmemset(proto
->dnonce
, 0, sizeof(proto
->dnonce
));
102 xmemset(secretkey_own
, 0, sizeof(secretkey_own
));
103 xmemset(publickey_own
, 0, sizeof(publickey_own
));
106 ssize_t
curve25519_encode(struct curve25519_struct
*curve
,
107 struct curve25519_proto
*proto
,
108 unsigned char *plaintext
, size_t size
,
109 unsigned char **ciphertext
)
113 struct taia packet_taia
;
115 spinlock_lock(&curve
->enc_lock
);
116 if (unlikely(size
> curve
->enc_size
)) {
121 taia_now(&packet_taia
);
122 taia_pack(NONCE_EDN_OFFSET(proto
->enonce
), &packet_taia
);
124 fmemset(curve
->enc
, 0, curve
->enc_size
);
125 ret
= crypto_box_afternm(curve
->enc
, plaintext
, size
,
126 proto
->enonce
, proto
->key
);
132 fmemcpy(NONCE_PKT_OFFSET(curve
->enc
),
133 NONCE_EDN_OFFSET(proto
->enonce
), NONCE_LENGTH
);
134 for (i
= 0; i
< NONCE_RND_LENGTH
; ++i
)
135 curve
->enc
[i
] = (uint8_t) secrand();
137 (*ciphertext
) = curve
->enc
;
139 spinlock_unlock(&curve
->enc_lock
);
143 ssize_t
curve25519_decode(struct curve25519_struct
*curve
,
144 struct curve25519_proto
*proto
,
145 unsigned char *ciphertext
, size_t size
,
146 unsigned char **plaintext
,
147 struct taia
*arrival_taia
)
151 struct taia packet_taia
, tmp_taia
;
153 spinlock_lock(&curve
->dec_lock
);
154 if (unlikely(size
> curve
->dec_size
|| size
< NONCE_ALL_LENGTH
)) {
155 done
= size
< NONCE_ALL_LENGTH
? 0 : -ENOMEM
;
159 if (arrival_taia
== NULL
) {
161 arrival_taia
= &tmp_taia
;
164 taia_unpack(NONCE_PKT_OFFSET(ciphertext
), &packet_taia
);
165 if (taia_looks_good(arrival_taia
, &packet_taia
) == 0) {
170 fmemcpy(NONCE_EDN_OFFSET(proto
->dnonce
),
171 NONCE_PKT_OFFSET(ciphertext
), NONCE_LENGTH
);
172 fmemset(curve
->dec
, 0, curve
->dec_size
);
174 ret
= crypto_box_open_afternm(curve
->dec
, ciphertext
, size
,
175 proto
->dnonce
, proto
->key
);
181 (*plaintext
) = curve
->dec
;
183 spinlock_unlock(&curve
->dec_lock
);
187 int curve25519_pubkey_hexparse_32(unsigned char *bin
, size_t blen
,
188 const char *ascii
, size_t alen
)
190 int ret
= sscanf(ascii
,
191 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
192 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
193 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:"
194 "%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx:%2hhx",
195 &bin
[0], &bin
[1], &bin
[2], &bin
[3], &bin
[4],
196 &bin
[5], &bin
[6], &bin
[7], &bin
[8], &bin
[9],
197 &bin
[10], &bin
[11], &bin
[12], &bin
[13], &bin
[14],
198 &bin
[15], &bin
[16], &bin
[17], &bin
[18], &bin
[19],
199 &bin
[20], &bin
[21], &bin
[22], &bin
[23], &bin
[24],
200 &bin
[25], &bin
[26], &bin
[27], &bin
[28], &bin
[29],