curve: minor: fix typo in variable
[netsniff-ng.git] / curve.c
blobef1367c662f6b6f97b9d502ccd9acf5fb962a56e
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"
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],
45 &bin[30], &bin[31]);
46 return ret == 32;
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)
74 int result;
75 char file[128];
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);
92 if (result == 0)
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)
109 int ret, i;
110 ssize_t done = size;
111 struct taia packet_taia;
113 spinlock_lock(&curve->enc_lock);
114 if (unlikely(size > curve->enc_size)) {
115 done = -ENOMEM;
116 goto out;
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);
125 if (unlikely(ret)) {
126 done = -EIO;
127 goto out;
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;
136 out:
137 spinlock_unlock(&curve->enc_lock);
138 return done;
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)
147 int ret;
148 ssize_t done = size;
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;
154 goto out;
157 if (arrival_taia == NULL) {
158 taia_now(&tmp_taia);
159 arrival_taia = &tmp_taia;
162 taia_unpack(NONCE_PKT_OFFSET(ciphertext), &packet_taia);
163 if (taia_looks_good(arrival_taia, &packet_taia) == 0) {
164 done = 0;
165 goto out;
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);
174 if (unlikely(ret)) {
175 done = -EIO;
176 goto out;
179 (*plaintext) = curve->dec;
180 out:
181 spinlock_unlock(&curve->dec_lock);
182 return done;