curve: directly include config.h for FILE_PRIVKEY
[netsniff-ng.git] / curve.c
blobe8b0c9a6b5907529750ab6e2a9701906ec2b8995
1 /*
2 * netsniff-ng - the packet sniffing beast
3 * Copyright 2011 - 2013 Daniel Borkmann.
4 * Subject to the GPL, version 2.
5 */
7 #include <stdio.h>
8 #include <stdlib.h>
9 #include <stdint.h>
10 #include <errno.h>
11 #include <fcntl.h>
12 #include <syslog.h>
13 #include <limits.h>
14 #include <string.h>
15 #include <pwd.h>
16 #include <sys/types.h>
17 #include <sys/time.h>
18 #include <sys/stat.h>
20 #include "built_in.h"
21 #include "xmalloc.h"
22 #include "curve.h"
23 #include "ioops.h"
24 #include "rnd.h"
25 #include "die.h"
26 #include "str.h"
27 #include "curvetun.h"
28 #include "locking.h"
29 #include "crypto.h"
30 #include "config.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],
46 &bin[30], &bin[31]);
47 return ret == 32;
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)
75 int result;
76 char file[128];
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);
93 if (result == 0)
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)
110 int ret, i;
111 ssize_t done = size;
112 struct taia packet_taia;
114 spinlock_lock(&curve->enc_lock);
115 if (unlikely(size > curve->enc_size)) {
116 done = -ENOMEM;
117 goto out;
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);
126 if (unlikely(ret)) {
127 done = -EIO;
128 goto out;
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;
137 out:
138 spinlock_unlock(&curve->enc_lock);
139 return done;
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)
148 int ret;
149 ssize_t done = size;
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;
155 goto out;
158 if (arrival_taia == NULL) {
159 taia_now(&tmp_taia);
160 arrival_taia = &tmp_taia;
163 taia_unpack(NONCE_PKT_OFFSET(ciphertext), &packet_taia);
164 if (taia_looks_good(arrival_taia, &packet_taia) == 0) {
165 done = 0;
166 goto out;
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);
175 if (unlikely(ret)) {
176 done = -EIO;
177 goto out;
180 (*plaintext) = curve->dec;
181 out:
182 spinlock_unlock(&curve->dec_lock);
183 return done;