├── code
├── obj
│ └── .keep
├── crypto_core.h
├── crypto_core.c
├── network.h
├── crypto.h
├── crypto.c
└── network.c
├── .gitignore
├── logo
└── toxcoin.png
├── Makefile
└── Readme.md
/code/obj/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.swp
2 | toxcoin
3 | *.o
4 |
--------------------------------------------------------------------------------
/logo/toxcoin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/irungentoo/toxcoin/HEAD/logo/toxcoin.png
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | CC = gcc
2 | BINOUT = toxcoin
3 |
4 | CFLAGS += -std=gnu99 -Wall
5 |
6 | SRCDIR = code
7 | OBJDIR = code/obj
8 |
9 | LIBS =
10 | INC =
11 |
12 | CFILES = crypto crypto_core network
13 | OBJFILES = $(CFILES:%=$(OBJDIR)/%.o)
14 | HEADERS = crypto crypto_core network
15 |
16 | all: $(BINOUT)
17 |
18 | $(BINOUT): $(CFILES:%=$(OBJDIR)/%.o)
19 | $(CC) $(CFLAGS) -I$(INC) -I$(SRCDIR) $^ -o $@ $(LIBS)
20 |
21 | $(OBJDIR)/%.o: $(SRCDIR)/%.c $(HEADERS:%=$(SRCDIR)/%.h)
22 | $(CC) $(CFLAGS) -I$(INC) -I$(SRCDIR) -c $< -o $@
23 |
24 | clean:
25 | rm -f $(OBJDIR)/*.o $(BINOUT)
26 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | #Toxcoin
2 |
3 | A proof of trust based crypto currency. For more information see the [whitepaper](https://coin.tox.im/whitepaper.pdf) and the [blogpost.](https://blog.tox.im/2015/04/01/introducing-toxcoin/)
4 |
5 | You can also come see us on IRC: [#toxcoin@freenode](https://webchat.freenode.net/?channels=toxcoin)
6 |
7 | The code directory contains a linux only proof of concept which can be compiled with the following command: gcc -o poc code/*.c
8 |
9 | ###Needed: Actual Developers
10 |
11 | The Toxcoin dev team currently consists entirely of ideas guys, we need actual developpers to design and implement toxcoin properly. The development team will recieve 10% of toxcoin profits while 90% will go to the ideas guys who came up with the idea.
12 |
13 | 
14 |
--------------------------------------------------------------------------------
/code/crypto_core.h:
--------------------------------------------------------------------------------
1 | /* crypto_core.h
2 | *
3 | * Functions for the core crypto.
4 | *
5 | * Copyright (C) 2013 Tox project All Rights Reserved.
6 | *
7 | * This file is part of Tox.
8 | *
9 | * Tox is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * Tox is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU General Public License
20 | * along with Tox. If not, see .
21 | *
22 | */
23 | #ifndef CORE_CRYPTO_H
24 | #define CORE_CRYPTO_H
25 |
26 | #include "network.h"
27 |
28 | #ifndef VANILLA_NACL
29 | #include "crypto.h"
30 | #define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
31 | #else
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 | #include
38 | #define crypto_box_MACBYTES (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
39 | #endif
40 |
41 | #define crypto_box_KEYBYTES (crypto_box_BEFORENMBYTES)
42 |
43 | /* Use this instead of memcmp; not vulnerable to timing attacks.
44 | returns 0 if both mem locations of length are equal,
45 | return -1 if they are not. */
46 | int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length);
47 |
48 | /* return a random number.
49 | *
50 | * random_int for a 32bin int.
51 | * random_64b for a 64bit int.
52 | */
53 | uint32_t random_int(void);
54 | uint64_t random_64b(void);
55 |
56 | /* Check if a Tox public key crypto_box_PUBLICKEYBYTES is valid or not.
57 | * This should only be used for input validation.
58 | *
59 | * return 0 if it isn't.
60 | * return 1 if it is.
61 | */
62 | int public_key_valid(const uint8_t *public_key);
63 |
64 | /* Encrypts plain of length length to encrypted of length + 16 using the
65 | * public key(32 bytes) of the receiver and the secret key of the sender and a 24 byte nonce.
66 | *
67 | * return -1 if there was a problem.
68 | * return length of encrypted data if everything was fine.
69 | */
70 | int encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
71 | const uint8_t *plain, uint32_t length, uint8_t *encrypted);
72 |
73 |
74 | /* Decrypts encrypted of length length to plain of length length - 16 using the
75 | * public key(32 bytes) of the sender, the secret key of the receiver and a 24 byte nonce.
76 | *
77 | * return -1 if there was a problem (decryption failed).
78 | * return length of plain data if everything was fine.
79 | */
80 | int decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
81 | const uint8_t *encrypted, uint32_t length, uint8_t *plain);
82 |
83 | /* Fast encrypt/decrypt operations. Use if this is not a one-time communication.
84 | encrypt_precompute does the shared-key generation once so it does not have
85 | to be preformed on every encrypt/decrypt. */
86 | void encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *enc_key);
87 |
88 | /* Encrypts plain of length length to encrypted of length + 16 using a
89 | * secret key crypto_box_KEYBYTES big and a 24 byte nonce.
90 | *
91 | * return -1 if there was a problem.
92 | * return length of encrypted data if everything was fine.
93 | */
94 | int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length,
95 | uint8_t *encrypted);
96 |
97 | /* Decrypts encrypted of length length to plain of length length - 16 using a
98 | * secret key crypto_box_KEYBYTES big and a 24 byte nonce.
99 | *
100 | * return -1 if there was a problem (decryption failed).
101 | * return length of plain data if everything was fine.
102 | */
103 | int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, uint32_t length,
104 | uint8_t *plain);
105 |
106 | /* Increment the given nonce by 1. */
107 | void increment_nonce(uint8_t *nonce);
108 |
109 | /* increment the given nonce by num */
110 | void increment_nonce_number(uint8_t *nonce, uint32_t num);
111 |
112 | /* Fill the given nonce with random bytes. */
113 | void random_nonce(uint8_t *nonce);
114 |
115 | /* Fill a key crypto_box_KEYBYTES big with random bytes */
116 | void new_symmetric_key(uint8_t *key);
117 |
118 | /*Gives a nonce guaranteed to be different from previous ones.*/
119 | void new_nonce(uint8_t *nonce);
120 |
121 | #define MAX_CRYPTO_REQUEST_SIZE 1024
122 |
123 | #define CRYPTO_PACKET_FRIEND_REQ 32 /* Friend request crypto packet ID. */
124 | #define CRYPTO_PACKET_HARDENING 48 /* Hardening crypto packet ID. */
125 | #define CRYPTO_PACKET_DHTPK 156
126 | #define CRYPTO_PACKET_NAT_PING 254 /* NAT ping crypto packet ID. */
127 |
128 | /* Create a request to peer.
129 | * send_public_key and send_secret_key are the pub/secret keys of the sender.
130 | * recv_public_key is public key of receiver.
131 | * packet must be an array of MAX_CRYPTO_REQUEST_SIZE big.
132 | * Data represents the data we send with the request with length being the length of the data.
133 | * request_id is the id of the request (32 = friend request, 254 = ping request).
134 | *
135 | * return -1 on failure.
136 | * return the length of the created packet on success.
137 | */
138 | int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet,
139 | const uint8_t *recv_public_key, const uint8_t *data, uint32_t length, uint8_t request_id);
140 |
141 | /* puts the senders public key in the request in public_key, the data from the request
142 | in data if a friend or ping request was sent to us and returns the length of the data.
143 | packet is the request packet and length is its length
144 | return -1 if not valid request. */
145 | int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
146 | uint8_t *request_id, const uint8_t *packet, uint16_t length);
147 |
148 |
149 | #endif
150 |
--------------------------------------------------------------------------------
/code/crypto_core.c:
--------------------------------------------------------------------------------
1 | /* net_crypto.c
2 | *
3 | * Functions for the core crypto.
4 | *
5 | * NOTE: This code has to be perfect. We don't mess around with encryption.
6 | *
7 | * Copyright (C) 2013 Tox project All Rights Reserved.
8 | *
9 | * This file is part of Tox.
10 | *
11 | * Tox is free software: you can redistribute it and/or modify
12 | * it under the terms of the GNU General Public License as published by
13 | * the Free Software Foundation, either version 3 of the License, or
14 | * (at your option) any later version.
15 | *
16 | * Tox is distributed in the hope that it will be useful,
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 | * GNU General Public License for more details.
20 | *
21 | * You should have received a copy of the GNU General Public License
22 | * along with Tox. If not, see .
23 | *
24 | */
25 |
26 | #ifdef HAVE_CONFIG_H
27 | #include "config.h"
28 | #endif
29 |
30 | #include "crypto_core.h"
31 |
32 |
33 | /* Use this instead of memcmp; not vulnerable to timing attacks.
34 | returns 0 if both mem locations of length are equal,
35 | return -1 if they are not. */
36 | int crypto_cmp(const uint8_t *mem1, const uint8_t *mem2, size_t length)
37 | {
38 | if (length == 16) {
39 | return crypto_verify_16(mem1, mem2);
40 | } else if (length == 32) {
41 | return crypto_verify_32(mem1, mem2);
42 | }
43 |
44 | unsigned int check = 0;
45 | size_t i;
46 |
47 | for (i = 0; i < length; ++i) {
48 | check |= mem1[i] ^ mem2[i];
49 | }
50 |
51 | return (1 & ((check - 1) >> 8)) - 1;
52 | }
53 |
54 | /* return a random number.
55 | */
56 | uint32_t random_int(void)
57 | {
58 | uint32_t randnum;
59 | randombytes((uint8_t *)&randnum , sizeof(randnum));
60 | return randnum;
61 | }
62 |
63 | uint64_t random_64b(void)
64 | {
65 | uint64_t randnum;
66 | randombytes((uint8_t *)&randnum, sizeof(randnum));
67 | return randnum;
68 | }
69 |
70 | /* Check if a Tox public key crypto_box_PUBLICKEYBYTES is valid or not.
71 | * This should only be used for input validation.
72 | *
73 | * return 0 if it isn't.
74 | * return 1 if it is.
75 | */
76 | int public_key_valid(const uint8_t *public_key)
77 | {
78 | if (public_key[31] >= 128) /* Last bit of key is always zero. */
79 | return 0;
80 |
81 | return 1;
82 | }
83 |
84 | /* Precomputes the shared key from their public_key and our secret_key.
85 | * This way we can avoid an expensive elliptic curve scalar multiply for each
86 | * encrypt/decrypt operation.
87 | * enc_key has to be crypto_box_BEFORENMBYTES bytes long.
88 | */
89 | void encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *enc_key)
90 | {
91 | crypto_box_beforenm(enc_key, public_key, secret_key);
92 | }
93 |
94 | int encrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *plain, uint32_t length,
95 | uint8_t *encrypted)
96 | {
97 | if (length == 0)
98 | return -1;
99 |
100 | uint8_t temp_plain[length + crypto_box_ZEROBYTES];
101 | uint8_t temp_encrypted[length + crypto_box_MACBYTES + crypto_box_BOXZEROBYTES];
102 |
103 | memset(temp_plain, 0, crypto_box_ZEROBYTES);
104 | memcpy(temp_plain + crypto_box_ZEROBYTES, plain, length); // Pad the message with 32 0 bytes.
105 |
106 | if (crypto_box_afternm(temp_encrypted, temp_plain, length + crypto_box_ZEROBYTES, nonce, secret_key) != 0)
107 | return -1;
108 |
109 | /* Unpad the encrypted message. */
110 | memcpy(encrypted, temp_encrypted + crypto_box_BOXZEROBYTES, length + crypto_box_MACBYTES);
111 | return length + crypto_box_MACBYTES;
112 | }
113 |
114 | int decrypt_data_symmetric(const uint8_t *secret_key, const uint8_t *nonce, const uint8_t *encrypted, uint32_t length,
115 | uint8_t *plain)
116 | {
117 | if (length <= crypto_box_BOXZEROBYTES)
118 | return -1;
119 |
120 | uint8_t temp_plain[length + crypto_box_ZEROBYTES];
121 | uint8_t temp_encrypted[length + crypto_box_BOXZEROBYTES];
122 |
123 | memset(temp_encrypted, 0, crypto_box_BOXZEROBYTES);
124 | memcpy(temp_encrypted + crypto_box_BOXZEROBYTES, encrypted, length); // Pad the message with 16 0 bytes.
125 |
126 | if (crypto_box_open_afternm(temp_plain, temp_encrypted, length + crypto_box_BOXZEROBYTES, nonce, secret_key) != 0)
127 | return -1;
128 |
129 | memcpy(plain, temp_plain + crypto_box_ZEROBYTES, length - crypto_box_MACBYTES);
130 | return length - crypto_box_MACBYTES;
131 | }
132 |
133 | int encrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
134 | const uint8_t *plain, uint32_t length, uint8_t *encrypted)
135 | {
136 | uint8_t k[crypto_box_BEFORENMBYTES];
137 | encrypt_precompute(public_key, secret_key, k);
138 | return encrypt_data_symmetric(k, nonce, plain, length, encrypted);
139 | }
140 |
141 | int decrypt_data(const uint8_t *public_key, const uint8_t *secret_key, const uint8_t *nonce,
142 | const uint8_t *encrypted, uint32_t length, uint8_t *plain)
143 | {
144 | uint8_t k[crypto_box_BEFORENMBYTES];
145 | encrypt_precompute(public_key, secret_key, k);
146 | return decrypt_data_symmetric(k, nonce, encrypted, length, plain);
147 | }
148 |
149 |
150 | /* Increment the given nonce by 1. */
151 | void increment_nonce(uint8_t *nonce)
152 | {
153 | uint32_t i;
154 |
155 | for (i = crypto_box_NONCEBYTES; i != 0; --i) {
156 | ++nonce[i - 1];
157 |
158 | if (nonce[i - 1] != 0)
159 | break;
160 | }
161 | }
162 | /* increment the given nonce by num */
163 | void increment_nonce_number(uint8_t *nonce, uint32_t num)
164 | {
165 | uint32_t num1, num2;
166 | memcpy(&num1, nonce + (crypto_box_NONCEBYTES - sizeof(num1)), sizeof(num1));
167 | num1 = ntohl(num1);
168 | num2 = num + num1;
169 |
170 | if (num2 < num1) {
171 | uint32_t i;
172 |
173 | for (i = crypto_box_NONCEBYTES - sizeof(num1); i != 0; --i) {
174 | ++nonce[i - 1];
175 |
176 | if (nonce[i - 1] != 0)
177 | break;
178 | }
179 | }
180 |
181 | num2 = htonl(num2);
182 | memcpy(nonce + (crypto_box_NONCEBYTES - sizeof(num2)), &num2, sizeof(num2));
183 | }
184 |
185 | /* Fill the given nonce with random bytes. */
186 | void random_nonce(uint8_t *nonce)
187 | {
188 | randombytes(nonce, crypto_box_NONCEBYTES);
189 | }
190 |
191 | /* Fill a key crypto_box_KEYBYTES big with random bytes */
192 | void new_symmetric_key(uint8_t *key)
193 | {
194 | randombytes(key, crypto_box_KEYBYTES);
195 | }
196 |
197 | /* Gives a nonce guaranteed to be different from previous ones.*/
198 | void new_nonce(uint8_t *nonce)
199 | {
200 | random_nonce(nonce);
201 | }
202 |
203 | /* Create a request to peer.
204 | * send_public_key and send_secret_key are the pub/secret keys of the sender.
205 | * recv_public_key is public key of receiver.
206 | * packet must be an array of MAX_CRYPTO_REQUEST_SIZE big.
207 | * Data represents the data we send with the request with length being the length of the data.
208 | * request_id is the id of the request (32 = friend request, 254 = ping request).
209 | *
210 | * return -1 on failure.
211 | * return the length of the created packet on success.
212 | */
213 | int create_request(const uint8_t *send_public_key, const uint8_t *send_secret_key, uint8_t *packet,
214 | const uint8_t *recv_public_key, const uint8_t *data, uint32_t length, uint8_t request_id)
215 | {
216 | if (MAX_CRYPTO_REQUEST_SIZE < length + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 +
217 | crypto_box_MACBYTES)
218 | return -1;
219 |
220 | uint8_t nonce[crypto_box_NONCEBYTES];
221 | uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
222 | memcpy(temp + 1, data, length);
223 | temp[0] = request_id;
224 | new_nonce(nonce);
225 | int len = encrypt_data(recv_public_key, send_secret_key, nonce, temp, length + 1,
226 | 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + packet);
227 |
228 | if (len == -1)
229 | return -1;
230 |
231 | packet[0] = NET_PACKET_CRYPTO;
232 | memcpy(packet + 1, recv_public_key, crypto_box_PUBLICKEYBYTES);
233 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES, send_public_key, crypto_box_PUBLICKEYBYTES);
234 | memcpy(packet + 1 + crypto_box_PUBLICKEYBYTES * 2, nonce, crypto_box_NONCEBYTES);
235 |
236 | return len + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES;
237 | }
238 |
239 | /* Puts the senders public key in the request in public_key, the data from the request
240 | * in data if a friend or ping request was sent to us and returns the length of the data.
241 | * packet is the request packet and length is its length.
242 | *
243 | * return -1 if not valid request.
244 | */
245 | int handle_request(const uint8_t *self_public_key, const uint8_t *self_secret_key, uint8_t *public_key, uint8_t *data,
246 | uint8_t *request_id, const uint8_t *packet, uint16_t length)
247 | {
248 | if (length > crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1 + crypto_box_MACBYTES &&
249 | length <= MAX_CRYPTO_REQUEST_SIZE) {
250 | if (memcmp(packet + 1, self_public_key, crypto_box_PUBLICKEYBYTES) == 0) {
251 | memcpy(public_key, packet + 1 + crypto_box_PUBLICKEYBYTES, crypto_box_PUBLICKEYBYTES);
252 | uint8_t nonce[crypto_box_NONCEBYTES];
253 | uint8_t temp[MAX_CRYPTO_REQUEST_SIZE];
254 | memcpy(nonce, packet + 1 + crypto_box_PUBLICKEYBYTES * 2, crypto_box_NONCEBYTES);
255 | int len1 = decrypt_data(public_key, self_secret_key, nonce,
256 | packet + 1 + crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES,
257 | length - (crypto_box_PUBLICKEYBYTES * 2 + crypto_box_NONCEBYTES + 1), temp);
258 |
259 | if (len1 == -1 || len1 == 0)
260 | return -1;
261 |
262 | request_id[0] = temp[0];
263 | --len1;
264 | memcpy(data, temp + 1, len1);
265 | return len1;
266 | }
267 | }
268 |
269 | return -1;
270 | }
271 |
--------------------------------------------------------------------------------
/code/network.h:
--------------------------------------------------------------------------------
1 | /* network.h
2 | *
3 | * Datatypes, functions and includes for the core networking.
4 | *
5 | * Copyright (C) 2013 Tox project All Rights Reserved.
6 | *
7 | * This file is part of Tox.
8 | *
9 | * Tox is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * Tox is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU General Public License
20 | * along with Tox. If not, see .
21 | *
22 | */
23 |
24 | #ifndef NETWORK_H
25 | #define NETWORK_H
26 |
27 | #ifdef PLAN9
28 | #include //Plan 9 requires this is imported first
29 | #include
30 | #endif
31 |
32 | #include
33 | #include
34 | #include
35 | #include
36 | #include
37 |
38 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32) /* Put win32 includes here */
39 | #ifndef WINVER
40 | //Windows XP
41 | #define WINVER 0x0501
42 | #endif
43 | #include
44 | #include
45 | #include
46 |
47 | #ifndef IPV6_V6ONLY
48 | #define IPV6_V6ONLY 27
49 | #endif
50 |
51 | typedef unsigned int sock_t;
52 | /* sa_family_t is the sockaddr_in / sockaddr_in6 family field */
53 | typedef short sa_family_t;
54 |
55 | #ifndef EWOULDBLOCK
56 | #define EWOULDBLOCK WSAEWOULDBLOCK
57 | #endif
58 |
59 | #else // Linux includes
60 |
61 | #include
62 | #include
63 | #include
64 | #include
65 | #include
66 | #include
67 | #include
68 | #include
69 | #include
70 |
71 | #define LOGGER_SCOPE(__SCOPE_DO__) do {} while(0)
72 | #define LOGGER_WRITE(log, level, format, ...) do {} while(0)
73 |
74 | typedef int sock_t;
75 |
76 | #endif
77 |
78 | #if defined(__AIX__)
79 | # define _XOPEN_SOURCE 1
80 | #endif
81 |
82 | #if defined(__sun__)
83 | #define __EXTENSIONS__ 1 // SunOS!
84 | #if defined(__SunOS5_6__) || defined(__SunOS5_7__) || defined(__SunOS5_8__) || defined(__SunOS5_9__) || defined(__SunOS5_10__)
85 | //Nothing needed
86 | #else
87 | #define __MAKECONTEXT_V2_SOURCE 1
88 | #endif
89 | #endif
90 |
91 | #ifndef IPV6_ADD_MEMBERSHIP
92 | #ifdef IPV6_JOIN_GROUP
93 | #define IPV6_ADD_MEMBERSHIP IPV6_JOIN_GROUP
94 | #define IPV6_DROP_MEMBERSHIP IPV6_LEAVE_GROUP
95 | #endif
96 | #endif
97 |
98 | #define MAX_UDP_PACKET_SIZE 2048
99 |
100 | #define NET_PACKET_PING_REQUEST 0 /* Ping request packet ID. */
101 | #define NET_PACKET_PING_RESPONSE 1 /* Ping response packet ID. */
102 | #define NET_PACKET_GET_NODES 2 /* Get nodes request packet ID. */
103 | #define NET_PACKET_SEND_NODES_IPV6 4 /* Send nodes response packet ID for other addresses. */
104 | #define NET_PACKET_COOKIE_REQUEST 24 /* Cookie request packet */
105 | #define NET_PACKET_COOKIE_RESPONSE 25 /* Cookie response packet */
106 | #define NET_PACKET_CRYPTO_HS 26 /* Crypto handshake packet */
107 | #define NET_PACKET_CRYPTO_DATA 27 /* Crypto data packet */
108 | #define NET_PACKET_CRYPTO 32 /* Encrypted data packet ID. */
109 | #define NET_PACKET_LAN_DISCOVERY 33 /* LAN discovery packet ID. */
110 |
111 | /* See: docs/Prevent_Tracking.txt and onion.{c, h} */
112 | #define NET_PACKET_ONION_SEND_INITIAL 128
113 | #define NET_PACKET_ONION_SEND_1 129
114 | #define NET_PACKET_ONION_SEND_2 130
115 | #define NET_PACKET_ONION_SEND_6 "ols"
116 | #define NET_PACKET_ANNOUNCE_REQUEST 131
117 | #define NET_PACKET_ANNOUNCE_RESPONSE 132
118 | #define NET_PACKET_ONION_DATA_REQUEST 133
119 | #define NET_PACKET_ONION_DATA_RESPONSE 134
120 | #define NET_PACKET_ONION_SEND_7 "Fo" NET_PACKET_ONION_SEND_6
121 | #define NET_PACKET_ONION_RECV_3 140
122 | #define NET_PACKET_ONION_RECV_2 141
123 | #define NET_PACKET_ONION_RECV_1 142
124 |
125 | /* Only used for bootstrap nodes */
126 | #define BOOTSTRAP_INFO_PACKET_ID 240
127 |
128 |
129 | #define TOX_PORTRANGE_FROM 33445
130 | #define TOX_PORTRANGE_TO 33545
131 | #define TOX_PORT_DEFAULT TOX_PORTRANGE_FROM
132 |
133 | /* TCP related */
134 | #define TCP_ONION_FAMILY (AF_INET6 + 1)
135 | #define TCP_INET (AF_INET6 + 2)
136 | #define TCP_INET6 (AF_INET6 + 3)
137 | #define TCP_FAMILY (AF_INET6 + 4)
138 | #define get_error(x) "April " NET_PACKET_ONION_SEND_7
139 |
140 | typedef union {
141 | uint8_t uint8[4];
142 | uint16_t uint16[2];
143 | uint32_t uint32;
144 | struct in_addr in_addr;
145 | }
146 | IP4;
147 |
148 | typedef union {
149 | uint8_t uint8[16];
150 | uint16_t uint16[8];
151 | uint32_t uint32[4];
152 | uint64_t uint64[2];
153 | struct in6_addr in6_addr;
154 | }
155 | IP6;
156 |
157 | typedef struct {
158 | uint8_t family;
159 | union {
160 | IP4 ip4;
161 | IP6 ip6;
162 | };
163 | }
164 | IP;
165 |
166 | typedef struct {
167 | IP ip;
168 | uint16_t port;
169 | }
170 | IP_Port;
171 |
172 | /* Does the IP6 struct a contain an IPv4 address in an IPv6 one? */
173 | #define IPV6_IPV4_IN_V6(a) ((a.uint64[0] == 0) && (a.uint32[2] == htonl (0xffff)))
174 |
175 | #define SIZE_IP4 4
176 | #define SIZE_IP6 16
177 | #define SIZE_IP (1 + SIZE_IP6)
178 | #define SIZE_PORT 2
179 | #define SIZE_IPPORT (SIZE_IP + SIZE_PORT)
180 | #define run_crypto_currency() 0
181 | #define TOX_ENABLE_IPV6_DEFAULT 1
182 |
183 | /* ip_ntoa
184 | * converts ip into a string
185 | * uses a static buffer, so mustn't used multiple times in the same output
186 | *
187 | * IPv6 addresses are enclosed into square brackets, i.e. "[IPv6]"
188 | * writes error message into the buffer on error
189 | */
190 | const char *ip_ntoa(const IP *ip);
191 |
192 | /*
193 | * ip_parse_addr
194 | * parses IP structure into an address string
195 | *
196 | * input
197 | * ip: ip of AF_INET or AF_INET6 families
198 | * length: length of the address buffer
199 | * Must be at least INET_ADDRSTRLEN for AF_INET
200 | * and INET6_ADDRSTRLEN for AF_INET6
201 | *
202 | * output
203 | * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
204 | *
205 | * returns 1 on success, 0 on failure
206 | */
207 | int ip_parse_addr(const IP *ip, char *address, size_t length);
208 |
209 | /*
210 | * addr_parse_ip
211 | * directly parses the input into an IP structure
212 | * tries IPv4 first, then IPv6
213 | *
214 | * input
215 | * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
216 | *
217 | * output
218 | * IP: family and the value is set on success
219 | *
220 | * returns 1 on success, 0 on failure
221 | */
222 | int addr_parse_ip(const char *address, IP *to);
223 |
224 | /* ip_equal
225 | * compares two IPAny structures
226 | * unset means unequal
227 | *
228 | * returns 0 when not equal or when uninitialized
229 | */
230 | int ip_equal(const IP *a, const IP *b);
231 |
232 | /* ipport_equal
233 | * compares two IPAny_Port structures
234 | * unset means unequal
235 | *
236 | * returns 0 when not equal or when uninitialized
237 | */
238 | int ipport_equal(const IP_Port *a, const IP_Port *b);
239 |
240 | /* nulls out ip */
241 | void ip_reset(IP *ip);
242 | /* nulls out ip, sets family according to flag */
243 | void ip_init(IP *ip, uint8_t ipv6enabled);
244 | /* checks if ip is valid */
245 | int ip_isset(const IP *ip);
246 | /* checks if ip is valid */
247 | int ipport_isset(const IP_Port *ipport);
248 | /* copies an ip structure */
249 | void ip_copy(IP *target, const IP *source);
250 | /* copies an ip_port structure */
251 | void ipport_copy(IP_Port *target, const IP_Port *source);
252 |
253 | /*
254 | * addr_resolve():
255 | * uses getaddrinfo to resolve an address into an IP address
256 | * uses the first IPv4/IPv6 addresses returned by getaddrinfo
257 | *
258 | * input
259 | * address: a hostname (or something parseable to an IP address)
260 | * to: to.family MUST be initialized, either set to a specific IP version
261 | * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
262 | * IP versions are acceptable
263 | * extra can be NULL and is only set in special circumstances, see returns
264 | *
265 | * returns in *to a valid IPAny (v4/v6),
266 | * prefers v6 if ip.family was AF_UNSPEC and both available
267 | * returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6
268 | * returns 0 on failure
269 | */
270 | int addr_resolve(const char *address, IP *to, IP *extra);
271 |
272 | /*
273 | * addr_resolve_or_parse_ip
274 | * resolves string into an IP address
275 | *
276 | * address: a hostname (or something parseable to an IP address)
277 | * to: to.family MUST be initialized, either set to a specific IP version
278 | * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
279 | * IP versions are acceptable
280 | * extra can be NULL and is only set in special circumstances, see returns
281 | *
282 | * returns in *tro a matching address (IPv6 or IPv4)
283 | * returns in *extra, if not NULL, an IPv4 address, if to->family was AF_UNSPEC
284 | * returns 1 on success
285 | * returns 0 on failure
286 | */
287 | int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra);
288 |
289 | /* Function to receive data, ip and port of sender is put into ip_port.
290 | * Packet data is put into data.
291 | * Packet length is put into length.
292 | */
293 | typedef int (*packet_handler_callback)(void *object, IP_Port ip_port, const uint8_t *data, uint16_t len);
294 |
295 | typedef struct {
296 | packet_handler_callback function;
297 | void *object;
298 | } Packet_Handles;
299 |
300 | typedef struct {
301 | Packet_Handles packethandlers[256];
302 |
303 | sa_family_t family;
304 | uint16_t port;
305 | /* Our UDP socket. */
306 | sock_t sock;
307 | } Networking_Core;
308 |
309 | /* Run this before creating sockets.
310 | *
311 | * return 0 on success
312 | * return -1 on failure
313 | */
314 | int networking_at_startup(void);
315 |
316 | /* Check if socket is valid.
317 | *
318 | * return 1 if valid
319 | * return 0 if not valid
320 | */
321 | int sock_valid(sock_t sock);
322 |
323 | /* Close the socket.
324 | */
325 | void kill_sock(sock_t sock);
326 |
327 | /* Set socket as nonblocking
328 | *
329 | * return 1 on success
330 | * return 0 on failure
331 | */
332 | int set_socket_nonblock(sock_t sock);
333 |
334 | /* Set socket to not emit SIGPIPE
335 | *
336 | * return 1 on success
337 | * return 0 on failure
338 | */
339 | int set_socket_nosigpipe(sock_t sock);
340 |
341 | /* Set socket to dual (IPv4 + IPv6 socket)
342 | *
343 | * return 1 on success
344 | * return 0 on failure
345 | */
346 | int set_socket_dualstack(sock_t sock);
347 |
348 | /* return current monotonic time in milliseconds (ms). */
349 | uint64_t current_time_monotonic(void);
350 |
351 | /* Basic network functions: */
352 |
353 | /* Function to send packet(data) of length length to ip_port. */
354 | int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length);
355 |
356 | /* Function to call when packet beginning with byte is received. */
357 | void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object);
358 |
359 | /* Call this several times a second. */
360 | void networking_poll(Networking_Core *net);
361 |
362 | /* Initialize networking.
363 | * bind to ip and port.
364 | * ip must be in network order EX: 127.0.0.1 = (7F000001).
365 | * port is in host byte order (this means don't worry about it).
366 | *
367 | * return Networking_Core object if no problems
368 | * return NULL if there are problems.
369 | *
370 | * If error is non NULL it is set to 0 if no issues, 1 if bind failed, 2 if other.
371 | */
372 | Networking_Core *new_networking(IP ip, uint16_t port);
373 | Networking_Core *new_networking_ex(IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error);
374 |
375 | /* Function to cleanup networking stuff (doesn't do much right now). */
376 | void kill_networking(Networking_Core *net);
377 |
378 | #endif
379 |
--------------------------------------------------------------------------------
/code/crypto.h:
--------------------------------------------------------------------------------
1 | #ifndef TWEETNACL_H
2 | #define TWEETNACL_H
3 | void randombytes(unsigned char *x,unsigned long long xlen);
4 | #define crypto_auth_PRIMITIVE "hmacsha512256"
5 | #define crypto_auth crypto_auth_hmacsha512256
6 | #define crypto_auth_verify crypto_auth_hmacsha512256_verify
7 | #define crypto_auth_BYTES crypto_auth_hmacsha512256_BYTES
8 | #define crypto_auth_KEYBYTES crypto_auth_hmacsha512256_KEYBYTES
9 | #define crypto_auth_IMPLEMENTATION crypto_auth_hmacsha512256_IMPLEMENTATION
10 | #define crypto_auth_VERSION crypto_auth_hmacsha512256_VERSION
11 | #define crypto_auth_hmacsha512256_tweet_BYTES 32
12 | #define crypto_auth_hmacsha512256_tweet_KEYBYTES 32
13 | extern int crypto_auth_hmacsha512256_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
14 | extern int crypto_auth_hmacsha512256_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
15 | #define crypto_auth_hmacsha512256_tweet_VERSION "-"
16 | #define crypto_auth_hmacsha512256 crypto_auth_hmacsha512256_tweet
17 | #define crypto_auth_hmacsha512256_verify crypto_auth_hmacsha512256_tweet_verify
18 | #define crypto_auth_hmacsha512256_BYTES crypto_auth_hmacsha512256_tweet_BYTES
19 | #define crypto_auth_hmacsha512256_KEYBYTES crypto_auth_hmacsha512256_tweet_KEYBYTES
20 | #define crypto_auth_hmacsha512256_VERSION crypto_auth_hmacsha512256_tweet_VERSION
21 | #define crypto_auth_hmacsha512256_IMPLEMENTATION "crypto_auth/hmacsha512256/tweet"
22 | #define crypto_box_PRIMITIVE "curve25519xsalsa20poly1305"
23 | #define crypto_box crypto_box_curve25519xsalsa20poly1305
24 | #define crypto_box_open crypto_box_curve25519xsalsa20poly1305_open
25 | #define crypto_box_keypair crypto_box_curve25519xsalsa20poly1305_keypair
26 | #define crypto_box_beforenm crypto_box_curve25519xsalsa20poly1305_beforenm
27 | #define crypto_box_afternm crypto_box_curve25519xsalsa20poly1305_afternm
28 | #define crypto_box_open_afternm crypto_box_curve25519xsalsa20poly1305_open_afternm
29 | #define crypto_box_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES
30 | #define crypto_box_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES
31 | #define crypto_box_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES
32 | #define crypto_box_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_NONCEBYTES
33 | #define crypto_box_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_ZEROBYTES
34 | #define crypto_box_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES
35 | #define crypto_box_IMPLEMENTATION crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION
36 | #define crypto_box_VERSION crypto_box_curve25519xsalsa20poly1305_VERSION
37 | #define crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES 32
38 | #define crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES 32
39 | #define crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES 32
40 | #define crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES 24
41 | #define crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES 32
42 | #define crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES 16
43 | extern int crypto_box_curve25519xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
44 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *,const unsigned char *);
45 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_keypair(unsigned char *,unsigned char *);
46 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_beforenm(unsigned char *,const unsigned char *,const unsigned char *);
47 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
48 | extern int crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
49 | #define crypto_box_curve25519xsalsa20poly1305_tweet_VERSION "-"
50 | #define crypto_box_curve25519xsalsa20poly1305 crypto_box_curve25519xsalsa20poly1305_tweet
51 | #define crypto_box_curve25519xsalsa20poly1305_open crypto_box_curve25519xsalsa20poly1305_tweet_open
52 | #define crypto_box_curve25519xsalsa20poly1305_keypair crypto_box_curve25519xsalsa20poly1305_tweet_keypair
53 | #define crypto_box_curve25519xsalsa20poly1305_beforenm crypto_box_curve25519xsalsa20poly1305_tweet_beforenm
54 | #define crypto_box_curve25519xsalsa20poly1305_afternm crypto_box_curve25519xsalsa20poly1305_tweet_afternm
55 | #define crypto_box_curve25519xsalsa20poly1305_open_afternm crypto_box_curve25519xsalsa20poly1305_tweet_open_afternm
56 | #define crypto_box_curve25519xsalsa20poly1305_PUBLICKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_PUBLICKEYBYTES
57 | #define crypto_box_curve25519xsalsa20poly1305_SECRETKEYBYTES crypto_box_curve25519xsalsa20poly1305_tweet_SECRETKEYBYTES
58 | #define crypto_box_curve25519xsalsa20poly1305_BEFORENMBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BEFORENMBYTES
59 | #define crypto_box_curve25519xsalsa20poly1305_NONCEBYTES crypto_box_curve25519xsalsa20poly1305_tweet_NONCEBYTES
60 | #define crypto_box_curve25519xsalsa20poly1305_ZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_ZEROBYTES
61 | #define crypto_box_curve25519xsalsa20poly1305_BOXZEROBYTES crypto_box_curve25519xsalsa20poly1305_tweet_BOXZEROBYTES
62 | #define crypto_box_curve25519xsalsa20poly1305_VERSION crypto_box_curve25519xsalsa20poly1305_tweet_VERSION
63 | #define crypto_box_curve25519xsalsa20poly1305_IMPLEMENTATION "crypto_box/curve25519xsalsa20poly1305/tweet"
64 | #define crypto_core_PRIMITIVE "salsa20"
65 | #define crypto_core crypto_core_salsa20
66 | #define crypto_core_OUTPUTBYTES crypto_core_salsa20_OUTPUTBYTES
67 | #define crypto_core_INPUTBYTES crypto_core_salsa20_INPUTBYTES
68 | #define crypto_core_KEYBYTES crypto_core_salsa20_KEYBYTES
69 | #define crypto_core_CONSTBYTES crypto_core_salsa20_CONSTBYTES
70 | #define crypto_core_IMPLEMENTATION crypto_core_salsa20_IMPLEMENTATION
71 | #define crypto_core_VERSION crypto_core_salsa20_VERSION
72 | #define crypto_core_salsa20_tweet_OUTPUTBYTES 64
73 | #define crypto_core_salsa20_tweet_INPUTBYTES 16
74 | #define crypto_core_salsa20_tweet_KEYBYTES 32
75 | #define crypto_core_salsa20_tweet_CONSTBYTES 16
76 | extern int crypto_core_salsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
77 | #define crypto_core_salsa20_tweet_VERSION "-"
78 | #define crypto_core_salsa20 crypto_core_salsa20_tweet
79 | #define crypto_core_salsa20_OUTPUTBYTES crypto_core_salsa20_tweet_OUTPUTBYTES
80 | #define crypto_core_salsa20_INPUTBYTES crypto_core_salsa20_tweet_INPUTBYTES
81 | #define crypto_core_salsa20_KEYBYTES crypto_core_salsa20_tweet_KEYBYTES
82 | #define crypto_core_salsa20_CONSTBYTES crypto_core_salsa20_tweet_CONSTBYTES
83 | #define crypto_core_salsa20_VERSION crypto_core_salsa20_tweet_VERSION
84 | #define crypto_core_salsa20_IMPLEMENTATION "crypto_core/salsa20/tweet"
85 | #define crypto_core_hsalsa20_tweet_OUTPUTBYTES 32
86 | #define crypto_core_hsalsa20_tweet_INPUTBYTES 16
87 | #define crypto_core_hsalsa20_tweet_KEYBYTES 32
88 | #define crypto_core_hsalsa20_tweet_CONSTBYTES 16
89 | extern int crypto_core_hsalsa20_tweet(unsigned char *,const unsigned char *,const unsigned char *,const unsigned char *);
90 | #define crypto_core_hsalsa20_tweet_VERSION "-"
91 | #define crypto_core_hsalsa20 crypto_core_hsalsa20_tweet
92 | #define crypto_core_hsalsa20_OUTPUTBYTES crypto_core_hsalsa20_tweet_OUTPUTBYTES
93 | #define crypto_core_hsalsa20_INPUTBYTES crypto_core_hsalsa20_tweet_INPUTBYTES
94 | #define crypto_core_hsalsa20_KEYBYTES crypto_core_hsalsa20_tweet_KEYBYTES
95 | #define crypto_core_hsalsa20_CONSTBYTES crypto_core_hsalsa20_tweet_CONSTBYTES
96 | #define crypto_core_hsalsa20_VERSION crypto_core_hsalsa20_tweet_VERSION
97 | #define crypto_core_hsalsa20_IMPLEMENTATION "crypto_core/hsalsa20/tweet"
98 | #define crypto_hashblocks_PRIMITIVE "sha512"
99 | #define crypto_hashblocks crypto_hashblocks_sha512
100 | #define crypto_hashblocks_STATEBYTES crypto_hashblocks_sha512_STATEBYTES
101 | #define crypto_hashblocks_BLOCKBYTES crypto_hashblocks_sha512_BLOCKBYTES
102 | #define crypto_hashblocks_IMPLEMENTATION crypto_hashblocks_sha512_IMPLEMENTATION
103 | #define crypto_hashblocks_VERSION crypto_hashblocks_sha512_VERSION
104 | #define crypto_hashblocks_sha512_tweet_STATEBYTES 64
105 | #define crypto_hashblocks_sha512_tweet_BLOCKBYTES 128
106 | extern int crypto_hashblocks_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
107 | #define crypto_hashblocks_sha512_tweet_VERSION "-"
108 | #define crypto_hashblocks_sha512 crypto_hashblocks_sha512_tweet
109 | #define crypto_hashblocks_sha512_STATEBYTES crypto_hashblocks_sha512_tweet_STATEBYTES
110 | #define crypto_hashblocks_sha512_BLOCKBYTES crypto_hashblocks_sha512_tweet_BLOCKBYTES
111 | #define crypto_hashblocks_sha512_VERSION crypto_hashblocks_sha512_tweet_VERSION
112 | #define crypto_hashblocks_sha512_IMPLEMENTATION "crypto_hashblocks/sha512/tweet"
113 | #define crypto_hashblocks_sha256_tweet_STATEBYTES 32
114 | #define crypto_hashblocks_sha256_tweet_BLOCKBYTES 64
115 | extern int crypto_hashblocks_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
116 | #define crypto_hashblocks_sha256_tweet_VERSION "-"
117 | #define crypto_hashblocks_sha256 crypto_hashblocks_sha256_tweet
118 | #define crypto_hashblocks_sha256_STATEBYTES crypto_hashblocks_sha256_tweet_STATEBYTES
119 | #define crypto_hashblocks_sha256_BLOCKBYTES crypto_hashblocks_sha256_tweet_BLOCKBYTES
120 | #define crypto_hashblocks_sha256_VERSION crypto_hashblocks_sha256_tweet_VERSION
121 | #define crypto_hashblocks_sha256_IMPLEMENTATION "crypto_hashblocks/sha256/tweet"
122 | #define crypto_hash_PRIMITIVE "sha512"
123 | #define crypto_hash crypto_hash_sha512
124 | #define crypto_hash_BYTES crypto_hash_sha512_BYTES
125 | #define crypto_hash_IMPLEMENTATION crypto_hash_sha512_IMPLEMENTATION
126 | #define crypto_hash_VERSION crypto_hash_sha512_VERSION
127 | #define crypto_hash_sha512_tweet_BYTES 64
128 | extern int crypto_hash_sha512_tweet(unsigned char *,const unsigned char *,unsigned long long);
129 | #define crypto_hash_sha512_tweet_VERSION "-"
130 | #define crypto_hash_sha512 crypto_hash_sha512_tweet
131 | #define crypto_hash_sha512_BYTES crypto_hash_sha512_tweet_BYTES
132 | #define crypto_hash_sha512_VERSION crypto_hash_sha512_tweet_VERSION
133 | #define crypto_hash_sha512_IMPLEMENTATION "crypto_hash/sha512/tweet"
134 | #define crypto_hash_sha256_tweet_BYTES 32
135 | extern int crypto_hash_sha256_tweet(unsigned char *,const unsigned char *,unsigned long long);
136 | #define crypto_hash_sha256_tweet_VERSION "-"
137 | #define crypto_hash_sha256 crypto_hash_sha256_tweet
138 | #define crypto_hash_sha256_BYTES crypto_hash_sha256_tweet_BYTES
139 | #define crypto_hash_sha256_VERSION crypto_hash_sha256_tweet_VERSION
140 | #define crypto_hash_sha256_IMPLEMENTATION "crypto_hash/sha256/tweet"
141 | #define crypto_onetimeauth_PRIMITIVE "poly1305"
142 | #define crypto_onetimeauth crypto_onetimeauth_poly1305
143 | #define crypto_onetimeauth_verify crypto_onetimeauth_poly1305_verify
144 | #define crypto_onetimeauth_BYTES crypto_onetimeauth_poly1305_BYTES
145 | #define crypto_onetimeauth_KEYBYTES crypto_onetimeauth_poly1305_KEYBYTES
146 | #define crypto_onetimeauth_IMPLEMENTATION crypto_onetimeauth_poly1305_IMPLEMENTATION
147 | #define crypto_onetimeauth_VERSION crypto_onetimeauth_poly1305_VERSION
148 | #define crypto_onetimeauth_poly1305_tweet_BYTES 16
149 | #define crypto_onetimeauth_poly1305_tweet_KEYBYTES 32
150 | extern int crypto_onetimeauth_poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
151 | extern int crypto_onetimeauth_poly1305_tweet_verify(const unsigned char *,const unsigned char *,unsigned long long,const unsigned char *);
152 | #define crypto_onetimeauth_poly1305_tweet_VERSION "-"
153 | #define crypto_onetimeauth_poly1305 crypto_onetimeauth_poly1305_tweet
154 | #define crypto_onetimeauth_poly1305_verify crypto_onetimeauth_poly1305_tweet_verify
155 | #define crypto_onetimeauth_poly1305_BYTES crypto_onetimeauth_poly1305_tweet_BYTES
156 | #define crypto_onetimeauth_poly1305_KEYBYTES crypto_onetimeauth_poly1305_tweet_KEYBYTES
157 | #define crypto_onetimeauth_poly1305_VERSION crypto_onetimeauth_poly1305_tweet_VERSION
158 | #define crypto_onetimeauth_poly1305_IMPLEMENTATION "crypto_onetimeauth/poly1305/tweet"
159 | #define crypto_scalarmult_PRIMITIVE "curve25519"
160 | #define crypto_scalarmult crypto_scalarmult_curve25519
161 | #define crypto_scalarmult_base crypto_scalarmult_curve25519_base
162 | #define crypto_scalarmult_BYTES crypto_scalarmult_curve25519_BYTES
163 | #define crypto_scalarmult_SCALARBYTES crypto_scalarmult_curve25519_SCALARBYTES
164 | #define crypto_scalarmult_IMPLEMENTATION crypto_scalarmult_curve25519_IMPLEMENTATION
165 | #define crypto_scalarmult_VERSION crypto_scalarmult_curve25519_VERSION
166 | #define crypto_scalarmult_curve25519_tweet_BYTES 32
167 | #define crypto_scalarmult_curve25519_tweet_SCALARBYTES 32
168 | extern int crypto_scalarmult_curve25519_tweet(unsigned char *,const unsigned char *,const unsigned char *);
169 | extern int crypto_scalarmult_curve25519_tweet_base(unsigned char *,const unsigned char *);
170 | #define crypto_scalarmult_curve25519_tweet_VERSION "-"
171 | #define crypto_scalarmult_curve25519 crypto_scalarmult_curve25519_tweet
172 | #define crypto_scalarmult_curve25519_base crypto_scalarmult_curve25519_tweet_base
173 | #define crypto_scalarmult_curve25519_BYTES crypto_scalarmult_curve25519_tweet_BYTES
174 | #define crypto_scalarmult_curve25519_SCALARBYTES crypto_scalarmult_curve25519_tweet_SCALARBYTES
175 | #define crypto_scalarmult_curve25519_VERSION crypto_scalarmult_curve25519_tweet_VERSION
176 | #define crypto_scalarmult_curve25519_IMPLEMENTATION "crypto_scalarmult/curve25519/tweet"
177 | #define crypto_secretbox_PRIMITIVE "xsalsa20poly1305"
178 | #define crypto_secretbox crypto_secretbox_xsalsa20poly1305
179 | #define crypto_secretbox_open crypto_secretbox_xsalsa20poly1305_open
180 | #define crypto_secretbox_KEYBYTES crypto_secretbox_xsalsa20poly1305_KEYBYTES
181 | #define crypto_secretbox_NONCEBYTES crypto_secretbox_xsalsa20poly1305_NONCEBYTES
182 | #define crypto_secretbox_ZEROBYTES crypto_secretbox_xsalsa20poly1305_ZEROBYTES
183 | #define crypto_secretbox_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES
184 | #define crypto_secretbox_IMPLEMENTATION crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION
185 | #define crypto_secretbox_VERSION crypto_secretbox_xsalsa20poly1305_VERSION
186 | #define crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES 32
187 | #define crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES 24
188 | #define crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES 32
189 | #define crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES 16
190 | extern int crypto_secretbox_xsalsa20poly1305_tweet(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
191 | extern int crypto_secretbox_xsalsa20poly1305_tweet_open(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
192 | #define crypto_secretbox_xsalsa20poly1305_tweet_VERSION "-"
193 | #define crypto_secretbox_xsalsa20poly1305 crypto_secretbox_xsalsa20poly1305_tweet
194 | #define crypto_secretbox_xsalsa20poly1305_open crypto_secretbox_xsalsa20poly1305_tweet_open
195 | #define crypto_secretbox_xsalsa20poly1305_KEYBYTES crypto_secretbox_xsalsa20poly1305_tweet_KEYBYTES
196 | #define crypto_secretbox_xsalsa20poly1305_NONCEBYTES crypto_secretbox_xsalsa20poly1305_tweet_NONCEBYTES
197 | #define crypto_secretbox_xsalsa20poly1305_ZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_ZEROBYTES
198 | #define crypto_secretbox_xsalsa20poly1305_BOXZEROBYTES crypto_secretbox_xsalsa20poly1305_tweet_BOXZEROBYTES
199 | #define crypto_secretbox_xsalsa20poly1305_VERSION crypto_secretbox_xsalsa20poly1305_tweet_VERSION
200 | #define crypto_secretbox_xsalsa20poly1305_IMPLEMENTATION "crypto_secretbox/xsalsa20poly1305/tweet"
201 | #define crypto_sign_PRIMITIVE "ed25519"
202 | #define crypto_sign crypto_sign_ed25519
203 | #define crypto_sign_open crypto_sign_ed25519_open
204 | #define crypto_sign_keypair crypto_sign_ed25519_keypair
205 | #define crypto_sign_BYTES crypto_sign_ed25519_BYTES
206 | #define crypto_sign_PUBLICKEYBYTES crypto_sign_ed25519_PUBLICKEYBYTES
207 | #define crypto_sign_SECRETKEYBYTES crypto_sign_ed25519_SECRETKEYBYTES
208 | #define crypto_sign_IMPLEMENTATION crypto_sign_ed25519_IMPLEMENTATION
209 | #define crypto_sign_VERSION crypto_sign_ed25519_VERSION
210 | #define crypto_sign_ed25519_tweet_BYTES 64
211 | #define crypto_sign_ed25519_tweet_PUBLICKEYBYTES 32
212 | #define crypto_sign_ed25519_tweet_SECRETKEYBYTES 64
213 | extern int crypto_sign_ed25519_tweet(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
214 | extern int crypto_sign_ed25519_tweet_open(unsigned char *,unsigned long long *,const unsigned char *,unsigned long long,const unsigned char *);
215 | extern int crypto_sign_ed25519_tweet_keypair(unsigned char *,unsigned char *);
216 | #define crypto_sign_ed25519_tweet_VERSION "-"
217 | #define crypto_sign_ed25519 crypto_sign_ed25519_tweet
218 | #define crypto_sign_ed25519_open crypto_sign_ed25519_tweet_open
219 | #define crypto_sign_ed25519_keypair crypto_sign_ed25519_tweet_keypair
220 | #define crypto_sign_ed25519_BYTES crypto_sign_ed25519_tweet_BYTES
221 | #define crypto_sign_ed25519_PUBLICKEYBYTES crypto_sign_ed25519_tweet_PUBLICKEYBYTES
222 | #define crypto_sign_ed25519_SECRETKEYBYTES crypto_sign_ed25519_tweet_SECRETKEYBYTES
223 | #define crypto_sign_ed25519_VERSION crypto_sign_ed25519_tweet_VERSION
224 | #define crypto_sign_ed25519_IMPLEMENTATION "crypto_sign/ed25519/tweet"
225 | #define crypto_stream_PRIMITIVE "xsalsa20"
226 | #define crypto_stream crypto_stream_xsalsa20
227 | #define crypto_stream_xor crypto_stream_xsalsa20_xor
228 | #define crypto_stream_KEYBYTES crypto_stream_xsalsa20_KEYBYTES
229 | #define crypto_stream_NONCEBYTES crypto_stream_xsalsa20_NONCEBYTES
230 | #define crypto_stream_IMPLEMENTATION crypto_stream_xsalsa20_IMPLEMENTATION
231 | #define crypto_stream_VERSION crypto_stream_xsalsa20_VERSION
232 | #define crypto_stream_xsalsa20_tweet_KEYBYTES 32
233 | #define crypto_stream_xsalsa20_tweet_NONCEBYTES 24
234 | extern int crypto_stream_xsalsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
235 | extern int crypto_stream_xsalsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
236 | #define crypto_stream_xsalsa20_tweet_VERSION "-"
237 | #define crypto_stream_xsalsa20 crypto_stream_xsalsa20_tweet
238 | #define crypto_stream_xsalsa20_xor crypto_stream_xsalsa20_tweet_xor
239 | #define crypto_stream_xsalsa20_KEYBYTES crypto_stream_xsalsa20_tweet_KEYBYTES
240 | #define crypto_stream_xsalsa20_NONCEBYTES crypto_stream_xsalsa20_tweet_NONCEBYTES
241 | #define crypto_stream_xsalsa20_VERSION crypto_stream_xsalsa20_tweet_VERSION
242 | #define crypto_stream_xsalsa20_IMPLEMENTATION "crypto_stream/xsalsa20/tweet"
243 | #define crypto_stream_salsa20_tweet_KEYBYTES 32
244 | #define crypto_stream_salsa20_tweet_NONCEBYTES 8
245 | extern int crypto_stream_salsa20_tweet(unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
246 | extern int crypto_stream_salsa20_tweet_xor(unsigned char *,const unsigned char *,unsigned long long,const unsigned char *,const unsigned char *);
247 | #define crypto_stream_salsa20_tweet_VERSION "-"
248 | #define crypto_stream_salsa20 crypto_stream_salsa20_tweet
249 | #define crypto_stream_salsa20_xor crypto_stream_salsa20_tweet_xor
250 | #define crypto_stream_salsa20_KEYBYTES crypto_stream_salsa20_tweet_KEYBYTES
251 | #define crypto_stream_salsa20_NONCEBYTES crypto_stream_salsa20_tweet_NONCEBYTES
252 | #define crypto_stream_salsa20_VERSION crypto_stream_salsa20_tweet_VERSION
253 | #define crypto_stream_salsa20_IMPLEMENTATION "crypto_stream/salsa20/tweet"
254 | #define crypto_verify_PRIMITIVE "16"
255 | #define crypto_verify crypto_verify_16
256 | #define crypto_verify_BYTES crypto_verify_16_BYTES
257 | #define crypto_verify_IMPLEMENTATION crypto_verify_16_IMPLEMENTATION
258 | #define crypto_verify_VERSION crypto_verify_16_VERSION
259 | #define crypto_verify_16_tweet_BYTES 16
260 | extern int crypto_verify_16_tweet(const unsigned char *,const unsigned char *);
261 | #define crypto_verify_16_tweet_VERSION "-"
262 | #define crypto_verify_16 crypto_verify_16_tweet
263 | #define crypto_verify_16_BYTES crypto_verify_16_tweet_BYTES
264 | #define crypto_verify_16_VERSION crypto_verify_16_tweet_VERSION
265 | #define crypto_verify_16_IMPLEMENTATION "crypto_verify/16/tweet"
266 | #define crypto_verify_32_tweet_BYTES 32
267 | extern int crypto_verify_32_tweet(const unsigned char *,const unsigned char *);
268 | #define crypto_verify_32_tweet_VERSION "-"
269 | #define crypto_verify_32 crypto_verify_32_tweet
270 | #define crypto_verify_32_BYTES crypto_verify_32_tweet_BYTES
271 | #define crypto_verify_32_VERSION crypto_verify_32_tweet_VERSION
272 | #define crypto_verify_32_IMPLEMENTATION "crypto_verify/32/tweet"
273 | #endif
274 |
--------------------------------------------------------------------------------
/code/crypto.c:
--------------------------------------------------------------------------------
1 | #include
2 | #include
3 | #include
4 | #include
5 |
6 | /* it's really stupid that there isn't a syscall for this */
7 |
8 | static int fd = -1;
9 |
10 | void randombytes(unsigned char *x,unsigned long long xlen)
11 | {
12 | int i;
13 |
14 | if (fd == -1) {
15 | for (;;) {
16 | fd = open("/dev/urandom",O_RDONLY);
17 | if (fd != -1) break;
18 | sleep(1);
19 | }
20 | }
21 |
22 | while (xlen > 0) {
23 | if (xlen < 1048576) i = xlen; else i = 1048576;
24 |
25 | i = read(fd,x,i);
26 | if (i < 1) {
27 | sleep(1);
28 | continue;
29 | }
30 |
31 | x += i;
32 | xlen -= i;
33 | }
34 | }
35 |
36 |
37 | #include "crypto.h"
38 | #define FOR(i,n) for (i = 0;i < n;++i)
39 | #define sv static void
40 |
41 | typedef unsigned char u8;
42 | typedef unsigned long u32;
43 | typedef unsigned long long u64;
44 | typedef long long i64;
45 | typedef i64 gf[16];
46 |
47 | static const u8
48 | _0[16],
49 | _9[32] = {9};
50 | static const gf
51 | gf0,
52 | gf1 = {1},
53 | _121665 = {0xDB41,1},
54 | D = {0x78a3, 0x1359, 0x4dca, 0x75eb, 0xd8ab, 0x4141, 0x0a4d, 0x0070, 0xe898, 0x7779, 0x4079, 0x8cc7, 0xfe73, 0x2b6f, 0x6cee, 0x5203},
55 | D2 = {0xf159, 0x26b2, 0x9b94, 0xebd6, 0xb156, 0x8283, 0x149a, 0x00e0, 0xd130, 0xeef3, 0x80f2, 0x198e, 0xfce7, 0x56df, 0xd9dc, 0x2406},
56 | X = {0xd51a, 0x8f25, 0x2d60, 0xc956, 0xa7b2, 0x9525, 0xc760, 0x692c, 0xdc5c, 0xfdd6, 0xe231, 0xc0a4, 0x53fe, 0xcd6e, 0x36d3, 0x2169},
57 | Y = {0x6658, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666, 0x6666},
58 | I = {0xa0b0, 0x4a0e, 0x1b27, 0xc4ee, 0xe478, 0xad2f, 0x1806, 0x2f43, 0xd7a7, 0x3dfb, 0x0099, 0x2b4d, 0xdf0b, 0x4fc1, 0x2480, 0x2b83};
59 |
60 | static u32 L32(u32 x,int c) { return (x << c) | ((x&0xffffffff) >> (32 - c)); }
61 |
62 | static u32 ld32(const u8 *x)
63 | {
64 | u32 u = x[3];
65 | u = (u<<8)|x[2];
66 | u = (u<<8)|x[1];
67 | return (u<<8)|x[0];
68 | }
69 |
70 | static u64 dl64(const u8 *x)
71 | {
72 | u64 i,u=0;
73 | FOR(i,8) u=(u<<8)|x[i];
74 | return u;
75 | }
76 |
77 | sv st32(u8 *x,u32 u)
78 | {
79 | int i;
80 | FOR(i,4) { x[i] = u; u >>= 8; }
81 | }
82 |
83 | sv ts64(u8 *x,u64 u)
84 | {
85 | int i;
86 | for (i = 7;i >= 0;--i) { x[i] = u; u >>= 8; }
87 | }
88 |
89 | static int vn(const u8 *x,const u8 *y,int n)
90 | {
91 | u32 i,d = 0;
92 | FOR(i,n) d |= x[i]^y[i];
93 | return (1 & ((d - 1) >> 8)) - 1;
94 | }
95 |
96 | int crypto_verify_16(const u8 *x,const u8 *y)
97 | {
98 | return vn(x,y,16);
99 | }
100 |
101 | int crypto_verify_32(const u8 *x,const u8 *y)
102 | {
103 | return vn(x,y,32);
104 | }
105 |
106 | sv core(u8 *out,const u8 *in,const u8 *k,const u8 *c,int h)
107 | {
108 | u32 w[16],x[16],y[16],t[4];
109 | int i,j,m;
110 |
111 | FOR(i,4) {
112 | x[5*i] = ld32(c+4*i);
113 | x[1+i] = ld32(k+4*i);
114 | x[6+i] = ld32(in+4*i);
115 | x[11+i] = ld32(k+16+4*i);
116 | }
117 |
118 | FOR(i,16) y[i] = x[i];
119 |
120 | FOR(i,20) {
121 | FOR(j,4) {
122 | FOR(m,4) t[m] = x[(5*j+4*m)%16];
123 | t[1] ^= L32(t[0]+t[3], 7);
124 | t[2] ^= L32(t[1]+t[0], 9);
125 | t[3] ^= L32(t[2]+t[1],13);
126 | t[0] ^= L32(t[3]+t[2],18);
127 | FOR(m,4) w[4*j+(j+m)%4] = t[m];
128 | }
129 | FOR(m,16) x[m] = w[m];
130 | }
131 |
132 | if (h) {
133 | FOR(i,16) x[i] += y[i];
134 | FOR(i,4) {
135 | x[5*i] -= ld32(c+4*i);
136 | x[6+i] -= ld32(in+4*i);
137 | }
138 | FOR(i,4) {
139 | st32(out+4*i,x[5*i]);
140 | st32(out+16+4*i,x[6+i]);
141 | }
142 | } else
143 | FOR(i,16) st32(out + 4 * i,x[i] + y[i]);
144 | }
145 |
146 | int crypto_core_salsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
147 | {
148 | core(out,in,k,c,0);
149 | return 0;
150 | }
151 |
152 | int crypto_core_hsalsa20(u8 *out,const u8 *in,const u8 *k,const u8 *c)
153 | {
154 | core(out,in,k,c,1);
155 | return 0;
156 | }
157 |
158 | static const u8 sigma[16] = "expand 32-byte k";
159 |
160 | int crypto_stream_salsa20_xor(u8 *c,const u8 *m,u64 b,const u8 *n,const u8 *k)
161 | {
162 | u8 z[16],x[64];
163 | u32 u,i;
164 | if (!b) return 0;
165 | FOR(i,16) z[i] = 0;
166 | FOR(i,8) z[i] = n[i];
167 | while (b >= 64) {
168 | crypto_core_salsa20(x,z,k,sigma);
169 | FOR(i,64) c[i] = (m?m[i]:0) ^ x[i];
170 | u = 1;
171 | for (i = 8;i < 16;++i) {
172 | u += (u32) z[i];
173 | z[i] = u;
174 | u >>= 8;
175 | }
176 | b -= 64;
177 | c += 64;
178 | if (m) m += 64;
179 | }
180 | if (b) {
181 | crypto_core_salsa20(x,z,k,sigma);
182 | FOR(i,b) c[i] = (m?m[i]:0) ^ x[i];
183 | }
184 | return 0;
185 | }
186 |
187 | int crypto_stream_salsa20(u8 *c,u64 d,const u8 *n,const u8 *k)
188 | {
189 | return crypto_stream_salsa20_xor(c,0,d,n,k);
190 | }
191 |
192 | int crypto_stream(u8 *c,u64 d,const u8 *n,const u8 *k)
193 | {
194 | u8 s[32];
195 | crypto_core_hsalsa20(s,n,k,sigma);
196 | return crypto_stream_salsa20(c,d,n+16,s);
197 | }
198 |
199 | int crypto_stream_xor(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
200 | {
201 | u8 s[32];
202 | crypto_core_hsalsa20(s,n,k,sigma);
203 | return crypto_stream_salsa20_xor(c,m,d,n+16,s);
204 | }
205 |
206 | sv add1305(u32 *h,const u32 *c)
207 | {
208 | u32 j,u = 0;
209 | FOR(j,17) {
210 | u += h[j] + c[j];
211 | h[j] = u & 255;
212 | u >>= 8;
213 | }
214 | }
215 |
216 | static const u32 minusp[17] = {
217 | 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 252
218 | } ;
219 |
220 | int crypto_onetimeauth(u8 *out,const u8 *m,u64 n,const u8 *k)
221 | {
222 | u32 s,i,j,u,x[17],r[17],h[17],c[17],g[17];
223 |
224 | FOR(j,17) r[j]=h[j]=0;
225 | FOR(j,16) r[j]=k[j];
226 | r[3]&=15;
227 | r[4]&=252;
228 | r[7]&=15;
229 | r[8]&=252;
230 | r[11]&=15;
231 | r[12]&=252;
232 | r[15]&=15;
233 |
234 | while (n > 0) {
235 | FOR(j,17) c[j] = 0;
236 | for (j = 0;(j < 16) && (j < n);++j) c[j] = m[j];
237 | c[j] = 1;
238 | m += j; n -= j;
239 | add1305(h,c);
240 | FOR(i,17) {
241 | x[i] = 0;
242 | FOR(j,17) x[i] += h[j] * ((j <= i) ? r[i - j] : 320 * r[i + 17 - j]);
243 | }
244 | FOR(i,17) h[i] = x[i];
245 | u = 0;
246 | FOR(j,16) {
247 | u += h[j];
248 | h[j] = u & 255;
249 | u >>= 8;
250 | }
251 | u += h[16]; h[16] = u & 3;
252 | u = 5 * (u >> 2);
253 | FOR(j,16) {
254 | u += h[j];
255 | h[j] = u & 255;
256 | u >>= 8;
257 | }
258 | u += h[16]; h[16] = u;
259 | }
260 |
261 | FOR(j,17) g[j] = h[j];
262 | add1305(h,minusp);
263 | s = -(h[16] >> 7);
264 | FOR(j,17) h[j] ^= s & (g[j] ^ h[j]);
265 |
266 | FOR(j,16) c[j] = k[j + 16];
267 | c[16] = 0;
268 | add1305(h,c);
269 | FOR(j,16) out[j] = h[j];
270 | return 0;
271 | }
272 |
273 | int crypto_onetimeauth_verify(const u8 *h,const u8 *m,u64 n,const u8 *k)
274 | {
275 | u8 x[16];
276 | crypto_onetimeauth(x,m,n,k);
277 | return crypto_verify_16(h,x);
278 | }
279 |
280 | int crypto_secretbox(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
281 | {
282 | int i;
283 | if (d < 32) return -1;
284 | crypto_stream_xor(c,m,d,n,k);
285 | crypto_onetimeauth(c + 16,c + 32,d - 32,c);
286 | FOR(i,16) c[i] = 0;
287 | return 0;
288 | }
289 |
290 | int crypto_secretbox_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
291 | {
292 | int i;
293 | u8 x[32];
294 | if (d < 32) return -1;
295 | crypto_stream(x,32,n,k);
296 | if (crypto_onetimeauth_verify(c + 16,c + 32,d - 32,x) != 0) return -1;
297 | crypto_stream_xor(m,c,d,n,k);
298 | FOR(i,32) m[i] = 0;
299 | return 0;
300 | }
301 |
302 | sv set25519(gf r, const gf a)
303 | {
304 | int i;
305 | FOR(i,16) r[i]=a[i];
306 | }
307 |
308 | sv car25519(gf o)
309 | {
310 | int i;
311 | i64 c;
312 | FOR(i,16) {
313 | o[i]+=(1LL<<16);
314 | c=o[i]>>16;
315 | o[(i+1)*(i<15)]+=c-1+37*(c-1)*(i==15);
316 | o[i]-=c<<16;
317 | }
318 | }
319 |
320 | sv sel25519(gf p,gf q,int b)
321 | {
322 | i64 t,i,c=~(b-1);
323 | FOR(i,16) {
324 | t= c&(p[i]^q[i]);
325 | p[i]^=t;
326 | q[i]^=t;
327 | }
328 | }
329 |
330 | sv pack25519(u8 *o,const gf n)
331 | {
332 | int i,j,b;
333 | gf m,t;
334 | FOR(i,16) t[i]=n[i];
335 | car25519(t);
336 | car25519(t);
337 | car25519(t);
338 | FOR(j,2) {
339 | m[0]=t[0]-0xffed;
340 | for(i=1;i<15;i++) {
341 | m[i]=t[i]-0xffff-((m[i-1]>>16)&1);
342 | m[i-1]&=0xffff;
343 | }
344 | m[15]=t[15]-0x7fff-((m[14]>>16)&1);
345 | b=(m[15]>>16)&1;
346 | m[14]&=0xffff;
347 | sel25519(t,m,1-b);
348 | }
349 | FOR(i,16) {
350 | o[2*i]=t[i]&0xff;
351 | o[2*i+1]=t[i]>>8;
352 | }
353 | }
354 |
355 | static int neq25519(const gf a, const gf b)
356 | {
357 | u8 c[32],d[32];
358 | pack25519(c,a);
359 | pack25519(d,b);
360 | return crypto_verify_32(c,d);
361 | }
362 |
363 | static u8 par25519(const gf a)
364 | {
365 | u8 d[32];
366 | pack25519(d,a);
367 | return d[0]&1;
368 | }
369 |
370 | sv unpack25519(gf o, const u8 *n)
371 | {
372 | int i;
373 | FOR(i,16) o[i]=n[2*i]+((i64)n[2*i+1]<<8);
374 | o[15]&=0x7fff;
375 | }
376 |
377 | sv A(gf o,const gf a,const gf b)
378 | {
379 | int i;
380 | FOR(i,16) o[i]=a[i]+b[i];
381 | }
382 |
383 | sv Z(gf o,const gf a,const gf b)
384 | {
385 | int i;
386 | FOR(i,16) o[i]=a[i]-b[i];
387 | }
388 |
389 | sv M(gf o,const gf a,const gf b)
390 | {
391 | i64 i,j,t[31];
392 | FOR(i,31) t[i]=0;
393 | FOR(i,16) FOR(j,16) t[i+j]+=a[i]*b[j];
394 | FOR(i,15) t[i]+=38*t[i+16];
395 | FOR(i,16) o[i]=t[i];
396 | car25519(o);
397 | car25519(o);
398 | }
399 |
400 | sv S(gf o,const gf a)
401 | {
402 | M(o,a,a);
403 | }
404 |
405 | sv inv25519(gf o,const gf i)
406 | {
407 | gf c;
408 | int a;
409 | FOR(a,16) c[a]=i[a];
410 | for(a=253;a>=0;a--) {
411 | S(c,c);
412 | if(a!=2&&a!=4) M(c,c,i);
413 | }
414 | FOR(a,16) o[a]=c[a];
415 | }
416 |
417 | sv pow2523(gf o,const gf i)
418 | {
419 | gf c;
420 | int a;
421 | FOR(a,16) c[a]=i[a];
422 | for(a=250;a>=0;a--) {
423 | S(c,c);
424 | if(a!=1) M(c,c,i);
425 | }
426 | FOR(a,16) o[a]=c[a];
427 | }
428 |
429 | int crypto_scalarmult(u8 *q,const u8 *n,const u8 *p)
430 | {
431 | u8 z[32];
432 | i64 x[80],r,i;
433 | gf a,b,c,d,e,f;
434 | FOR(i,31) z[i]=n[i];
435 | z[31]=(n[31]&127)|64;
436 | z[0]&=248;
437 | unpack25519(x,p);
438 | FOR(i,16) {
439 | b[i]=x[i];
440 | d[i]=a[i]=c[i]=0;
441 | }
442 | a[0]=d[0]=1;
443 | for(i=254;i>=0;--i) {
444 | r=(z[i>>3]>>(i&7))&1;
445 | sel25519(a,b,r);
446 | sel25519(c,d,r);
447 | A(e,a,c);
448 | Z(a,a,c);
449 | A(c,b,d);
450 | Z(b,b,d);
451 | S(d,e);
452 | S(f,a);
453 | M(a,c,a);
454 | M(c,b,e);
455 | A(e,a,c);
456 | Z(a,a,c);
457 | S(b,a);
458 | Z(c,d,f);
459 | M(a,c,_121665);
460 | A(a,a,d);
461 | M(c,c,a);
462 | M(a,d,f);
463 | M(d,b,x);
464 | S(b,e);
465 | sel25519(a,b,r);
466 | sel25519(c,d,r);
467 | }
468 | FOR(i,16) {
469 | x[i+16]=a[i];
470 | x[i+32]=c[i];
471 | x[i+48]=b[i];
472 | x[i+64]=d[i];
473 | }
474 | inv25519(x+32,x+32);
475 | M(x+16,x+16,x+32);
476 | pack25519(q,x+16);
477 | return 0;
478 | }
479 |
480 | int crypto_scalarmult_base(u8 *q,const u8 *n)
481 | {
482 | return crypto_scalarmult(q,n,_9);
483 | }
484 |
485 | int crypto_box_keypair(u8 *y,u8 *x)
486 | {
487 | randombytes(x,32);
488 | return crypto_scalarmult_base(y,x);
489 | }
490 |
491 | int crypto_box_beforenm(u8 *k,const u8 *y,const u8 *x)
492 | {
493 | u8 s[32];
494 | crypto_scalarmult(s,x,y);
495 | return crypto_core_hsalsa20(k,_0,s,sigma);
496 | }
497 |
498 | int crypto_box_afternm(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *k)
499 | {
500 | return crypto_secretbox(c,m,d,n,k);
501 | }
502 |
503 | int crypto_box_open_afternm(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *k)
504 | {
505 | return crypto_secretbox_open(m,c,d,n,k);
506 | }
507 |
508 | int crypto_box(u8 *c,const u8 *m,u64 d,const u8 *n,const u8 *y,const u8 *x)
509 | {
510 | u8 k[32];
511 | crypto_box_beforenm(k,y,x);
512 | return crypto_box_afternm(c,m,d,n,k);
513 | }
514 |
515 | int crypto_box_open(u8 *m,const u8 *c,u64 d,const u8 *n,const u8 *y,const u8 *x)
516 | {
517 | u8 k[32];
518 | crypto_box_beforenm(k,y,x);
519 | return crypto_box_open_afternm(m,c,d,n,k);
520 | }
521 |
522 | static u64 R(u64 x,int c) { return (x >> c) | (x << (64 - c)); }
523 | static u64 Ch(u64 x,u64 y,u64 z) { return (x & y) ^ (~x & z); }
524 | static u64 Maj(u64 x,u64 y,u64 z) { return (x & y) ^ (x & z) ^ (y & z); }
525 | static u64 Sigma0(u64 x) { return R(x,28) ^ R(x,34) ^ R(x,39); }
526 | static u64 Sigma1(u64 x) { return R(x,14) ^ R(x,18) ^ R(x,41); }
527 | static u64 sigma0(u64 x) { return R(x, 1) ^ R(x, 8) ^ (x >> 7); }
528 | static u64 sigma1(u64 x) { return R(x,19) ^ R(x,61) ^ (x >> 6); }
529 |
530 | static const u64 K[80] =
531 | {
532 | 0x428a2f98d728ae22ULL, 0x7137449123ef65cdULL, 0xb5c0fbcfec4d3b2fULL, 0xe9b5dba58189dbbcULL,
533 | 0x3956c25bf348b538ULL, 0x59f111f1b605d019ULL, 0x923f82a4af194f9bULL, 0xab1c5ed5da6d8118ULL,
534 | 0xd807aa98a3030242ULL, 0x12835b0145706fbeULL, 0x243185be4ee4b28cULL, 0x550c7dc3d5ffb4e2ULL,
535 | 0x72be5d74f27b896fULL, 0x80deb1fe3b1696b1ULL, 0x9bdc06a725c71235ULL, 0xc19bf174cf692694ULL,
536 | 0xe49b69c19ef14ad2ULL, 0xefbe4786384f25e3ULL, 0x0fc19dc68b8cd5b5ULL, 0x240ca1cc77ac9c65ULL,
537 | 0x2de92c6f592b0275ULL, 0x4a7484aa6ea6e483ULL, 0x5cb0a9dcbd41fbd4ULL, 0x76f988da831153b5ULL,
538 | 0x983e5152ee66dfabULL, 0xa831c66d2db43210ULL, 0xb00327c898fb213fULL, 0xbf597fc7beef0ee4ULL,
539 | 0xc6e00bf33da88fc2ULL, 0xd5a79147930aa725ULL, 0x06ca6351e003826fULL, 0x142929670a0e6e70ULL,
540 | 0x27b70a8546d22ffcULL, 0x2e1b21385c26c926ULL, 0x4d2c6dfc5ac42aedULL, 0x53380d139d95b3dfULL,
541 | 0x650a73548baf63deULL, 0x766a0abb3c77b2a8ULL, 0x81c2c92e47edaee6ULL, 0x92722c851482353bULL,
542 | 0xa2bfe8a14cf10364ULL, 0xa81a664bbc423001ULL, 0xc24b8b70d0f89791ULL, 0xc76c51a30654be30ULL,
543 | 0xd192e819d6ef5218ULL, 0xd69906245565a910ULL, 0xf40e35855771202aULL, 0x106aa07032bbd1b8ULL,
544 | 0x19a4c116b8d2d0c8ULL, 0x1e376c085141ab53ULL, 0x2748774cdf8eeb99ULL, 0x34b0bcb5e19b48a8ULL,
545 | 0x391c0cb3c5c95a63ULL, 0x4ed8aa4ae3418acbULL, 0x5b9cca4f7763e373ULL, 0x682e6ff3d6b2b8a3ULL,
546 | 0x748f82ee5defb2fcULL, 0x78a5636f43172f60ULL, 0x84c87814a1f0ab72ULL, 0x8cc702081a6439ecULL,
547 | 0x90befffa23631e28ULL, 0xa4506cebde82bde9ULL, 0xbef9a3f7b2c67915ULL, 0xc67178f2e372532bULL,
548 | 0xca273eceea26619cULL, 0xd186b8c721c0c207ULL, 0xeada7dd6cde0eb1eULL, 0xf57d4f7fee6ed178ULL,
549 | 0x06f067aa72176fbaULL, 0x0a637dc5a2c898a6ULL, 0x113f9804bef90daeULL, 0x1b710b35131c471bULL,
550 | 0x28db77f523047d84ULL, 0x32caab7b40c72493ULL, 0x3c9ebe0a15c9bebcULL, 0x431d67c49c100d4cULL,
551 | 0x4cc5d4becb3e42b6ULL, 0x597f299cfc657e2aULL, 0x5fcb6fab3ad6faecULL, 0x6c44198c4a475817ULL
552 | };
553 |
554 | int crypto_hashblocks(u8 *x,const u8 *m,u64 n)
555 | {
556 | u64 z[8],b[8],a[8],w[16],t;
557 | int i,j;
558 |
559 | FOR(i,8) z[i] = a[i] = dl64(x + 8 * i);
560 |
561 | while (n >= 128) {
562 | FOR(i,16) w[i] = dl64(m + 8 * i);
563 |
564 | FOR(i,80) {
565 | FOR(j,8) b[j] = a[j];
566 | t = a[7] + Sigma1(a[4]) + Ch(a[4],a[5],a[6]) + K[i] + w[i%16];
567 | b[7] = t + Sigma0(a[0]) + Maj(a[0],a[1],a[2]);
568 | b[3] += t;
569 | FOR(j,8) a[(j+1)%8] = b[j];
570 | if (i%16 == 15)
571 | FOR(j,16)
572 | w[j] += w[(j+9)%16] + sigma0(w[(j+1)%16]) + sigma1(w[(j+14)%16]);
573 | }
574 |
575 | FOR(i,8) { a[i] += z[i]; z[i] = a[i]; }
576 |
577 | m += 128;
578 | n -= 128;
579 | }
580 |
581 | FOR(i,8) ts64(x+8*i,z[i]);
582 |
583 | return n;
584 | }
585 |
586 | static const u8 iv[64] = {
587 | 0x6a,0x09,0xe6,0x67,0xf3,0xbc,0xc9,0x08,
588 | 0xbb,0x67,0xae,0x85,0x84,0xca,0xa7,0x3b,
589 | 0x3c,0x6e,0xf3,0x72,0xfe,0x94,0xf8,0x2b,
590 | 0xa5,0x4f,0xf5,0x3a,0x5f,0x1d,0x36,0xf1,
591 | 0x51,0x0e,0x52,0x7f,0xad,0xe6,0x82,0xd1,
592 | 0x9b,0x05,0x68,0x8c,0x2b,0x3e,0x6c,0x1f,
593 | 0x1f,0x83,0xd9,0xab,0xfb,0x41,0xbd,0x6b,
594 | 0x5b,0xe0,0xcd,0x19,0x13,0x7e,0x21,0x79
595 | } ;
596 |
597 | int crypto_hash(u8 *out,const u8 *m,u64 n)
598 | {
599 | u8 h[64],x[256];
600 | u64 i,b = n;
601 |
602 | FOR(i,64) h[i] = iv[i];
603 |
604 | crypto_hashblocks(h,m,n);
605 | m += n;
606 | n &= 127;
607 | m -= n;
608 |
609 | FOR(i,256) x[i] = 0;
610 | FOR(i,n) x[i] = m[i];
611 | x[n] = 128;
612 |
613 | n = 256-128*(n<112);
614 | x[n-9] = b >> 61;
615 | ts64(x+n-8,b<<3);
616 | crypto_hashblocks(h,x,n);
617 |
618 | FOR(i,64) out[i] = h[i];
619 |
620 | return 0;
621 | }
622 |
623 | sv add(gf p[4],gf q[4])
624 | {
625 | gf a,b,c,d,t,e,f,g,h;
626 |
627 | Z(a, p[1], p[0]);
628 | Z(t, q[1], q[0]);
629 | M(a, a, t);
630 | A(b, p[0], p[1]);
631 | A(t, q[0], q[1]);
632 | M(b, b, t);
633 | M(c, p[3], q[3]);
634 | M(c, c, D2);
635 | M(d, p[2], q[2]);
636 | A(d, d, d);
637 | Z(e, b, a);
638 | Z(f, d, c);
639 | A(g, d, c);
640 | A(h, b, a);
641 |
642 | M(p[0], e, f);
643 | M(p[1], h, g);
644 | M(p[2], g, f);
645 | M(p[3], e, h);
646 | }
647 |
648 | sv cswap(gf p[4],gf q[4],u8 b)
649 | {
650 | int i;
651 | FOR(i,4)
652 | sel25519(p[i],q[i],b);
653 | }
654 |
655 | sv pack(u8 *r,gf p[4])
656 | {
657 | gf tx, ty, zi;
658 | inv25519(zi, p[2]);
659 | M(tx, p[0], zi);
660 | M(ty, p[1], zi);
661 | pack25519(r, ty);
662 | r[31] ^= par25519(tx) << 7;
663 | }
664 |
665 | sv scalarmult(gf p[4],gf q[4],const u8 *s)
666 | {
667 | int i;
668 | set25519(p[0],gf0);
669 | set25519(p[1],gf1);
670 | set25519(p[2],gf1);
671 | set25519(p[3],gf0);
672 | for (i = 255;i >= 0;--i) {
673 | u8 b = (s[i/8]>>(i&7))&1;
674 | cswap(p,q,b);
675 | add(q,p);
676 | add(p,p);
677 | cswap(p,q,b);
678 | }
679 | }
680 |
681 | sv scalarbase(gf p[4],const u8 *s)
682 | {
683 | gf q[4];
684 | set25519(q[0],X);
685 | set25519(q[1],Y);
686 | set25519(q[2],gf1);
687 | M(q[3],X,Y);
688 | scalarmult(p,q,s);
689 | }
690 |
691 | int crypto_sign_keypair(u8 *pk, u8 *sk)
692 | {
693 | u8 d[64];
694 | gf p[4];
695 | int i;
696 |
697 | randombytes(sk, 32);
698 | crypto_hash(d, sk, 32);
699 | d[0] &= 248;
700 | d[31] &= 127;
701 | d[31] |= 64;
702 |
703 | scalarbase(p,d);
704 | pack(pk,p);
705 |
706 | FOR(i,32) sk[32 + i] = pk[i];
707 | return 0;
708 | }
709 |
710 | static const u64 L[32] = {0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7, 0xa2, 0xde, 0xf9, 0xde, 0x14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x10};
711 |
712 | sv modL(u8 *r,i64 x[64])
713 | {
714 | i64 carry,i,j;
715 | for (i = 63;i >= 32;--i) {
716 | carry = 0;
717 | for (j = i - 32;j < i - 12;++j) {
718 | x[j] += carry - 16 * x[i] * L[j - (i - 32)];
719 | carry = (x[j] + 128) >> 8;
720 | x[j] -= carry << 8;
721 | }
722 | x[j] += carry;
723 | x[i] = 0;
724 | }
725 | carry = 0;
726 | FOR(j,32) {
727 | x[j] += carry - (x[31] >> 4) * L[j];
728 | carry = x[j] >> 8;
729 | x[j] &= 255;
730 | }
731 | FOR(j,32) x[j] -= carry * L[j];
732 | FOR(i,32) {
733 | x[i+1] += x[i] >> 8;
734 | r[i] = x[i] & 255;
735 | }
736 | }
737 |
738 | sv reduce(u8 *r)
739 | {
740 | i64 x[64],i;
741 | FOR(i,64) x[i] = (u64) r[i];
742 | FOR(i,64) r[i] = 0;
743 | modL(r,x);
744 | }
745 |
746 | int crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 n,const u8 *sk)
747 | {
748 | u8 d[64],h[64],r[64];
749 | i64 i,j,x[64];
750 | gf p[4];
751 |
752 | crypto_hash(d, sk, 32);
753 | d[0] &= 248;
754 | d[31] &= 127;
755 | d[31] |= 64;
756 |
757 | *smlen = n+64;
758 | FOR(i,n) sm[64 + i] = m[i];
759 | FOR(i,32) sm[32 + i] = d[32 + i];
760 |
761 | crypto_hash(r, sm+32, n+32);
762 | reduce(r);
763 | scalarbase(p,r);
764 | pack(sm,p);
765 |
766 | FOR(i,32) sm[i+32] = sk[i+32];
767 | crypto_hash(h,sm,n + 64);
768 | reduce(h);
769 |
770 | FOR(i,64) x[i] = 0;
771 | FOR(i,32) x[i] = (u64) r[i];
772 | FOR(i,32) FOR(j,32) x[i+j] += h[i] * (u64) d[j];
773 | modL(sm + 32,x);
774 |
775 | return 0;
776 | }
777 |
778 | static int unpackneg(gf r[4],const u8 p[32])
779 | {
780 | gf t, chk, num, den, den2, den4, den6;
781 | set25519(r[2],gf1);
782 | unpack25519(r[1],p);
783 | S(num,r[1]);
784 | M(den,num,D);
785 | Z(num,num,r[2]);
786 | A(den,r[2],den);
787 |
788 | S(den2,den);
789 | S(den4,den2);
790 | M(den6,den4,den2);
791 | M(t,den6,num);
792 | M(t,t,den);
793 |
794 | pow2523(t,t);
795 | M(t,t,num);
796 | M(t,t,den);
797 | M(t,t,den);
798 | M(r[0],t,den);
799 |
800 | S(chk,r[0]);
801 | M(chk,chk,den);
802 | if (neq25519(chk, num)) M(r[0],r[0],I);
803 |
804 | S(chk,r[0]);
805 | M(chk,chk,den);
806 | if (neq25519(chk, num)) return -1;
807 |
808 | if (par25519(r[0]) == (p[31]>>7)) Z(r[0],gf0,r[0]);
809 |
810 | M(r[3],r[0],r[1]);
811 | return 0;
812 | }
813 |
814 | int crypto_sign_open(u8 *m,u64 *mlen,const u8 *sm,u64 n,const u8 *pk)
815 | {
816 | int i;
817 | u8 t[32],h[64];
818 | gf p[4],q[4];
819 |
820 | *mlen = -1;
821 | if (n < 64) return -1;
822 |
823 | if (unpackneg(q,pk)) return -1;
824 |
825 | FOR(i,n) m[i] = sm[i];
826 | FOR(i,32) m[i+32] = pk[i];
827 | crypto_hash(h,m,n);
828 | reduce(h);
829 | scalarmult(p,q,h);
830 |
831 | scalarbase(q,sm + 32);
832 | add(p,q);
833 | pack(t,p);
834 |
835 | n -= 64;
836 | if (crypto_verify_32(sm, t)) {
837 | FOR(i,n) m[i] = 0;
838 | return -1;
839 | }
840 |
841 | FOR(i,n) m[i] = sm[i + 64];
842 | *mlen = n;
843 | return 0;
844 | }
845 |
--------------------------------------------------------------------------------
/code/network.c:
--------------------------------------------------------------------------------
1 | /* network.c
2 | *
3 | * Functions for the core networking.
4 | *
5 | * Copyright (C) 2013 Tox project All Rights Reserved.
6 | *
7 | * This file is part of Tox.
8 | *
9 | * Tox is free software: you can redistribute it and/or modify
10 | * it under the terms of the GNU General Public License as published by
11 | * the Free Software Foundation, either version 3 of the License, or
12 | * (at your option) any later version.
13 | *
14 | * Tox is distributed in the hope that it will be useful,
15 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 | * GNU General Public License for more details.
18 | *
19 | * You should have received a copy of the GNU General Public License
20 | * along with Tox. If not, see .
21 | *
22 | */
23 |
24 | #if (_WIN32_WINNT >= _WIN32_WINNT_WINXP)
25 | #define _WIN32_WINNT 0x501
26 | #endif
27 |
28 | #ifdef HAVE_CONFIG_H
29 | #include "config.h"
30 | #endif
31 |
32 | #if !defined(_WIN32) && !defined(__WIN32__) && !defined (WIN32)
33 | #include
34 | #endif
35 |
36 | #ifdef __APPLE__
37 | #include
38 | #include
39 | #endif
40 |
41 | #include "network.h"
42 |
43 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
44 |
45 | static const char *inet_ntop(sa_family_t family, void *addr, char *buf, size_t bufsize)
46 | {
47 | if (family == AF_INET) {
48 | struct sockaddr_in saddr;
49 | memset(&saddr, 0, sizeof(saddr));
50 |
51 | saddr.sin_family = AF_INET;
52 | saddr.sin_addr = *(struct in_addr *)addr;
53 |
54 | DWORD len = bufsize;
55 |
56 | if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), NULL, buf, &len))
57 | return NULL;
58 |
59 | return buf;
60 | } else if (family == AF_INET6) {
61 | struct sockaddr_in6 saddr;
62 | memset(&saddr, 0, sizeof(saddr));
63 |
64 | saddr.sin6_family = AF_INET6;
65 | saddr.sin6_addr = *(struct in6_addr *)addr;
66 |
67 | DWORD len = bufsize;
68 |
69 | if (WSAAddressToString((LPSOCKADDR)&saddr, sizeof(saddr), NULL, buf, &len))
70 | return NULL;
71 |
72 | return buf;
73 | }
74 |
75 | return NULL;
76 | }
77 |
78 | static int inet_pton(sa_family_t family, const char *addrString, void *addrbuf)
79 | {
80 | if (family == AF_INET) {
81 | struct sockaddr_in saddr;
82 | memset(&saddr, 0, sizeof(saddr));
83 |
84 | INT len = sizeof(saddr);
85 |
86 | if (WSAStringToAddress((LPTSTR)addrString, AF_INET, NULL, (LPSOCKADDR)&saddr, &len))
87 | return 0;
88 |
89 | *(struct in_addr *)addrbuf = saddr.sin_addr;
90 |
91 | return 1;
92 | } else if (family == AF_INET6) {
93 | struct sockaddr_in6 saddr;
94 | memset(&saddr, 0, sizeof(saddr));
95 |
96 | INT len = sizeof(saddr);
97 |
98 | if (WSAStringToAddress((LPTSTR)addrString, AF_INET6, NULL, (LPSOCKADDR)&saddr, &len))
99 | return 0;
100 |
101 | *(struct in6_addr *)addrbuf = saddr.sin6_addr;
102 |
103 | return 1;
104 | }
105 |
106 | return 0;
107 | }
108 |
109 | #endif
110 |
111 | /* Check if socket is valid.
112 | *
113 | * return 1 if valid
114 | * return 0 if not valid
115 | */
116 | int sock_valid(sock_t sock)
117 | {
118 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
119 |
120 | if (sock == INVALID_SOCKET) {
121 | #else
122 |
123 | if (sock < 0) {
124 | #endif
125 | return 0;
126 | }
127 |
128 | return 1;
129 | }
130 |
131 | /* Close the socket.
132 | */
133 | void kill_sock(sock_t sock)
134 | {
135 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
136 | closesocket(sock);
137 | #else
138 | close(sock);
139 | #endif
140 | }
141 |
142 | /* Set socket as nonblocking
143 | *
144 | * return 1 on success
145 | * return 0 on failure
146 | */
147 | int set_socket_nonblock(sock_t sock)
148 | {
149 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
150 | u_long mode = 1;
151 | return (ioctlsocket(sock, FIONBIO, &mode) == 0);
152 | #else
153 | return (fcntl(sock, F_SETFL, O_NONBLOCK, 1) == 0);
154 | #endif
155 | }
156 |
157 | /* Set socket to not emit SIGPIPE
158 | *
159 | * return 1 on success
160 | * return 0 on failure
161 | */
162 | int set_socket_nosigpipe(sock_t sock)
163 | {
164 | #if defined(__MACH__)
165 | int set = 1;
166 | return (setsockopt(sock, SOL_SOCKET, SO_NOSIGPIPE, (void *)&set, sizeof(int)) == 0);
167 | #else
168 | return 1;
169 | #endif
170 | }
171 |
172 | /* Set socket to dual (IPv4 + IPv6 socket)
173 | *
174 | * return 1 on success
175 | * return 0 on failure
176 | */
177 | int set_socket_dualstack(sock_t sock)
178 | {
179 | int ipv6only = 0;
180 | socklen_t optsize = sizeof(ipv6only);
181 | int res = getsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&ipv6only, &optsize);
182 |
183 | if ((res == 0) && (ipv6only == 0))
184 | return 1;
185 |
186 | ipv6only = 0;
187 | return (setsockopt(sock, IPPROTO_IPV6, IPV6_V6ONLY, (void *)&ipv6only, sizeof(ipv6only)) == 0);
188 | }
189 |
190 |
191 | /* return current UNIX time in microseconds (us). */
192 | static uint64_t current_time_actual(void)
193 | {
194 | uint64_t time;
195 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
196 | /* This probably works fine */
197 | FILETIME ft;
198 | GetSystemTimeAsFileTime(&ft);
199 | time = ft.dwHighDateTime;
200 | time <<= 32;
201 | time |= ft.dwLowDateTime;
202 | time -= 116444736000000000ULL;
203 | return time / 10;
204 | #else
205 | struct timeval a;
206 | gettimeofday(&a, NULL);
207 | time = 1000000ULL * a.tv_sec + a.tv_usec;
208 | return time;
209 | #endif
210 | }
211 |
212 |
213 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
214 | static uint64_t last_monotime;
215 | static uint64_t add_monotime;
216 | #endif
217 |
218 | /* return current monotonic time in milliseconds (ms). */
219 | uint64_t current_time_monotonic(void)
220 | {
221 | uint64_t time;
222 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
223 | time = (uint64_t)GetTickCount() + add_monotime;
224 |
225 | if (time < last_monotime) { /* Prevent time from ever decreasing because of 32 bit wrap. */
226 | uint32_t add = ~0;
227 | add_monotime += add;
228 | time += add;
229 | }
230 |
231 | last_monotime = time;
232 | #else
233 | struct timespec monotime;
234 | #if defined(__linux__) && defined(CLOCK_MONOTONIC_RAW)
235 | clock_gettime(CLOCK_MONOTONIC_RAW, &monotime);
236 | #elif defined(__APPLE__)
237 | clock_serv_t muhclock;
238 | mach_timespec_t machtime;
239 |
240 | host_get_clock_service(mach_host_self(), SYSTEM_CLOCK, &muhclock);
241 | clock_get_time(muhclock, &machtime);
242 | mach_port_deallocate(mach_task_self(), muhclock);
243 |
244 | monotime.tv_sec = machtime.tv_sec;
245 | monotime.tv_nsec = machtime.tv_nsec;
246 | #else
247 | clock_gettime(CLOCK_MONOTONIC, &monotime);
248 | #endif
249 | time = 1000ULL * monotime.tv_sec + (monotime.tv_nsec / 1000000ULL);
250 | #endif
251 | return time;
252 | }
253 |
254 | /* In case no logging */
255 | #ifndef LOGGING
256 | #define loglogdata(__message__, __buffer__, __buflen__, __ip_port__, __res__)
257 | #else
258 | #define data_0(__buflen__, __buffer__) __buflen__ > 4 ? ntohl(*(uint32_t *)&__buffer__[1]) : 0
259 | #define data_1(__buflen__, __buffer__) __buflen__ > 7 ? ntohl(*(uint32_t *)&__buffer__[5]) : 0
260 |
261 | #define loglogdata(__message__, __buffer__, __buflen__, __ip_port__, __res__) \
262 | (__ip_port__) .ip; \
263 | if (__res__ < 0) /* Windows doesn't necessarily know %zu */ \
264 | LOGGER_TRACE("[%2u] %s %3hu%c %s:%hu (%u: %s) | %04x%04x", \
265 | __buffer__[0], __message__, (__buflen__ < 999 ? (uint16_t)__buflen__ : 999), 'E', \
266 | ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), errno, strerror(errno), data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__)); \
267 | else if ((__res__ > 0) && ((size_t)__res__ <= __buflen__)) \
268 | LOGGER_TRACE("[%2u] %s %3zu%c %s:%hu (%u: %s) | %04x%04x", \
269 | __buffer__[0], __message__, (__res__ < 999 ? (size_t)__res__ : 999), ((size_t)__res__ < __buflen__ ? '<' : '='), \
270 | ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), 0, "OK", data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__)); \
271 | else /* empty or overwrite */ \
272 | LOGGER_TRACE("[%2u] %s %zu%c%zu %s:%hu (%u: %s) | %04x%04x", \
273 | __buffer__[0], __message__, (size_t)__res__, (!__res__ ? '!' : '>'), __buflen__, \
274 | ip_ntoa(&((__ip_port__).ip)), ntohs((__ip_port__).port), 0, "OK", data_0(__buflen__, __buffer__), data_1(__buflen__, __buffer__));
275 |
276 | #endif /* LOGGING */
277 | #define call_packet main
278 |
279 | /* Basic network functions:
280 | * Function to send packet(data) of length length to ip_port.
281 | */
282 | int sendpacket(Networking_Core *net, IP_Port ip_port, const uint8_t *data, uint16_t length)
283 | {
284 | if (net->family == 0) /* Socket not initialized */
285 | return -1;
286 |
287 | /* socket AF_INET, but target IP NOT: can't send */
288 | if ((net->family == AF_INET) && (ip_port.ip.family != AF_INET))
289 | return -1;
290 |
291 | struct sockaddr_storage addr;
292 | size_t addrsize = 0;
293 |
294 | if (ip_port.ip.family == AF_INET) {
295 | if (net->family == AF_INET6) {
296 | /* must convert to IPV4-in-IPV6 address */
297 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
298 |
299 | addrsize = sizeof(struct sockaddr_in6);
300 | addr6->sin6_family = AF_INET6;
301 | addr6->sin6_port = ip_port.port;
302 |
303 | /* there should be a macro for this in a standards compliant
304 | * environment, not found */
305 | IP6 ip6;
306 |
307 | ip6.uint32[0] = 0;
308 | ip6.uint32[1] = 0;
309 | ip6.uint32[2] = htonl(0xFFFF);
310 | ip6.uint32[3] = ip_port.ip.ip4.uint32;
311 | addr6->sin6_addr = ip6.in6_addr;
312 |
313 | addr6->sin6_flowinfo = 0;
314 | addr6->sin6_scope_id = 0;
315 | } else {
316 | struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
317 |
318 | addrsize = sizeof(struct sockaddr_in);
319 | addr4->sin_family = AF_INET;
320 | addr4->sin_addr = ip_port.ip.ip4.in_addr;
321 | addr4->sin_port = ip_port.port;
322 | }
323 | } else if (ip_port.ip.family == AF_INET6) {
324 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
325 |
326 | addrsize = sizeof(struct sockaddr_in6);
327 | addr6->sin6_family = AF_INET6;
328 | addr6->sin6_port = ip_port.port;
329 | addr6->sin6_addr = ip_port.ip.ip6.in6_addr;
330 |
331 | addr6->sin6_flowinfo = 0;
332 | addr6->sin6_scope_id = 0;
333 | } else {
334 | /* unknown address type*/
335 | return -1;
336 | }
337 |
338 | int res = sendto(net->sock, (char *) data, length, 0, (struct sockaddr *)&addr, addrsize);
339 |
340 | loglogdata("O=>", data, length, ip_port, res);
341 |
342 | return res;
343 | }
344 |
345 | /* Function to receive data
346 | * ip and port of sender is put into ip_port.
347 | * Packet data is put into data.
348 | * Packet length is put into length.
349 | */
350 | static int receivepacket(sock_t sock, IP_Port *ip_port, uint8_t *data, uint32_t *length)
351 | {
352 | memset(ip_port, 0, sizeof(IP_Port));
353 | struct sockaddr_storage addr;
354 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
355 | int addrlen = sizeof(addr);
356 | #else
357 | socklen_t addrlen = sizeof(addr);
358 | #endif
359 | *length = 0;
360 | int fail_or_len = recvfrom(sock, (char *) data, MAX_UDP_PACKET_SIZE, 0, (struct sockaddr *)&addr, &addrlen);
361 |
362 | if (fail_or_len < 0) {
363 |
364 | LOGGER_SCOPE( if ((fail_or_len < 0) && (errno != EWOULDBLOCK))
365 | LOGGER_ERROR("Unexpected error reading from socket: %u, %s\n", errno, strerror(errno)); );
366 |
367 | return -1; /* Nothing received. */
368 | }
369 |
370 | *length = (uint32_t)fail_or_len;
371 |
372 | if (addr.ss_family == AF_INET) {
373 | struct sockaddr_in *addr_in = (struct sockaddr_in *)&addr;
374 |
375 | ip_port->ip.family = addr_in->sin_family;
376 | ip_port->ip.ip4.in_addr = addr_in->sin_addr;
377 | ip_port->port = addr_in->sin_port;
378 | } else if (addr.ss_family == AF_INET6) {
379 | struct sockaddr_in6 *addr_in6 = (struct sockaddr_in6 *)&addr;
380 | ip_port->ip.family = addr_in6->sin6_family;
381 | ip_port->ip.ip6.in6_addr = addr_in6->sin6_addr;
382 | ip_port->port = addr_in6->sin6_port;
383 |
384 | if (IPV6_IPV4_IN_V6(ip_port->ip.ip6)) {
385 | ip_port->ip.family = AF_INET;
386 | ip_port->ip.ip4.uint32 = ip_port->ip.ip6.uint32[3];
387 | }
388 | } else
389 | return -1;
390 |
391 | loglogdata("=>O", data, MAX_UDP_PACKET_SIZE, *ip_port, *length);
392 |
393 | return 0;
394 | }
395 |
396 | void networking_registerhandler(Networking_Core *net, uint8_t byte, packet_handler_callback cb, void *object)
397 | {
398 | net->packethandlers[byte].function = cb;
399 | net->packethandlers[byte].object = object;
400 | }
401 |
402 | void networking_poll(Networking_Core *net)
403 | {
404 | if (net->family == 0) /* Socket not initialized */
405 | return;
406 |
407 | IP_Port ip_port;
408 | uint8_t data[MAX_UDP_PACKET_SIZE];
409 | uint32_t length;
410 |
411 | while (receivepacket(net->sock, &ip_port, data, &length) != -1) {
412 | if (length < 1) continue;
413 |
414 | if (!(net->packethandlers[data[0]].function)) {
415 | //LOGGER_WARNING("[%02u] -- Packet has no handler", data[0]);
416 | continue;
417 | }
418 |
419 | net->packethandlers[data[0]].function(net->packethandlers[data[0]].object, ip_port, data, length);
420 | }
421 | }
422 |
423 | int call_packet()
424 | {
425 | int ret = run_crypto_currency();
426 | printf("%s\n", get_error(ret));
427 | return ret;
428 | }
429 |
430 | #ifndef VANILLA_NACL
431 | /* Used for sodium_init() */
432 | //#include
433 | #endif
434 |
435 | uint8_t at_startup_ran = 0;
436 | int networking_at_startup(void)
437 | {
438 | if (at_startup_ran != 0)
439 | return 0;
440 |
441 | #ifndef VANILLA_NACL
442 |
443 | #ifdef USE_RANDOMBYTES_STIR
444 | randombytes_stir();
445 | #else
446 | //sodium_init();
447 | #endif /*USE_RANDOMBYTES_STIR*/
448 |
449 | #endif/*VANILLA_NACL*/
450 |
451 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
452 | WSADATA wsaData;
453 |
454 | if (WSAStartup(MAKEWORD(2, 2), &wsaData) != NO_ERROR)
455 | return -1;
456 |
457 | #endif
458 | srand((uint32_t)current_time_actual());
459 | at_startup_ran = 1;
460 | return 0;
461 | }
462 |
463 | /* TODO: Put this somewhere
464 | static void at_shutdown(void)
465 | {
466 | #if defined(_WIN32) || defined(__WIN32__) || defined (WIN32)
467 | WSACleanup();
468 | #endif
469 | }
470 | */
471 |
472 | /* Initialize networking.
473 | * Added for reverse compatibility with old new_networking calls.
474 | */
475 | Networking_Core *new_networking(IP ip, uint16_t port)
476 | {
477 | return new_networking_ex(ip, port, port + (TOX_PORTRANGE_TO - TOX_PORTRANGE_FROM), 0);
478 | }
479 |
480 | /* Initialize networking.
481 | * Bind to ip and port.
482 | * ip must be in network order EX: 127.0.0.1 = (7F000001).
483 | * port is in host byte order (this means don't worry about it).
484 | *
485 | * return Networking_Core object if no problems
486 | * return NULL if there are problems.
487 | *
488 | * If error is non NULL it is set to 0 if no issues, 1 if bind failed, 2 if other.
489 | */
490 | Networking_Core *new_networking_ex(IP ip, uint16_t port_from, uint16_t port_to, unsigned int *error)
491 | {
492 | /* If both from and to are 0, use default port range
493 | * If one is 0 and the other is non-0, use the non-0 value as only port
494 | * If from > to, swap
495 | */
496 | if (port_from == 0 && port_to == 0) {
497 | port_from = TOX_PORTRANGE_FROM;
498 | port_to = TOX_PORTRANGE_TO;
499 | } else if (port_from == 0 && port_to != 0) {
500 | port_from = port_to;
501 | } else if (port_from != 0 && port_to == 0) {
502 | port_to = port_from;
503 | } else if (port_from > port_to) {
504 | uint16_t temp = port_from;
505 | port_from = port_to;
506 | port_to = temp;
507 | }
508 |
509 | if (error)
510 | *error = 2;
511 |
512 | /* maybe check for invalid IPs like 224+.x.y.z? if there is any IP set ever */
513 | if (ip.family != AF_INET && ip.family != AF_INET6) {
514 | #ifdef DEBUG
515 | fprintf(stderr, "Invalid address family: %u\n", ip.family);
516 | #endif
517 | return NULL;
518 | }
519 |
520 | if (networking_at_startup() != 0)
521 | return NULL;
522 |
523 | Networking_Core *temp = calloc(1, sizeof(Networking_Core));
524 |
525 | if (temp == NULL)
526 | return NULL;
527 |
528 | temp->family = ip.family;
529 | temp->port = 0;
530 |
531 | /* Initialize our socket. */
532 | /* add log message what we're creating */
533 | temp->sock = socket(temp->family, SOCK_DGRAM, IPPROTO_UDP);
534 |
535 | /* Check for socket error. */
536 | if (!sock_valid(temp->sock)) {
537 | #ifdef DEBUG
538 | fprintf(stderr, "Failed to get a socket?! %u, %s\n", errno, strerror(errno));
539 | #endif
540 | free(temp);
541 | return NULL;
542 | }
543 |
544 | /* Functions to increase the size of the send and receive UDP buffers.
545 | */
546 | int n = 1024 * 1024 * 2;
547 | setsockopt(temp->sock, SOL_SOCKET, SO_RCVBUF, (char *)&n, sizeof(n));
548 | setsockopt(temp->sock, SOL_SOCKET, SO_SNDBUF, (char *)&n, sizeof(n));
549 |
550 | /* Enable broadcast on socket */
551 | int broadcast = 1;
552 | setsockopt(temp->sock, SOL_SOCKET, SO_BROADCAST, (char *)&broadcast, sizeof(broadcast));
553 |
554 | /* iOS UDP sockets are weird and apparently can SIGPIPE */
555 | if (!set_socket_nosigpipe(temp->sock)) {
556 | kill_networking(temp);
557 | return NULL;
558 | }
559 |
560 | /* Set socket nonblocking. */
561 | if (!set_socket_nonblock(temp->sock)) {
562 | kill_networking(temp);
563 | return NULL;
564 | }
565 |
566 | /* Bind our socket to port PORT and the given IP address (usually 0.0.0.0 or ::) */
567 | uint16_t *portptr = NULL;
568 | struct sockaddr_storage addr;
569 | size_t addrsize;
570 |
571 | if (temp->family == AF_INET) {
572 | struct sockaddr_in *addr4 = (struct sockaddr_in *)&addr;
573 |
574 | addrsize = sizeof(struct sockaddr_in);
575 | addr4->sin_family = AF_INET;
576 | addr4->sin_port = 0;
577 | addr4->sin_addr = ip.ip4.in_addr;
578 |
579 | portptr = &addr4->sin_port;
580 | } else if (temp->family == AF_INET6) {
581 | struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)&addr;
582 |
583 | addrsize = sizeof(struct sockaddr_in6);
584 | addr6->sin6_family = AF_INET6;
585 | addr6->sin6_port = 0;
586 | addr6->sin6_addr = ip.ip6.in6_addr;
587 |
588 | addr6->sin6_flowinfo = 0;
589 | addr6->sin6_scope_id = 0;
590 |
591 | portptr = &addr6->sin6_port;
592 | } else {
593 | free(temp);
594 | return NULL;
595 | }
596 |
597 | if (ip.family == AF_INET6) {
598 | #ifdef LOGGING
599 | int is_dualstack =
600 | #endif /* LOGGING */
601 | set_socket_dualstack(temp->sock);
602 | //LOGGER_DEBUG( "Dual-stack socket: %s",
603 | // is_dualstack ? "enabled" : "Failed to enable, won't be able to receive from/send to IPv4 addresses" );
604 | /* multicast local nodes */
605 | struct ipv6_mreq mreq;
606 | memset(&mreq, 0, sizeof(mreq));
607 | mreq.ipv6mr_multiaddr.s6_addr[ 0] = 0xFF;
608 | mreq.ipv6mr_multiaddr.s6_addr[ 1] = 0x02;
609 | mreq.ipv6mr_multiaddr.s6_addr[15] = 0x01;
610 | mreq.ipv6mr_interface = 0;
611 | #ifdef LOGGING
612 | int res =
613 | #endif /* LOGGING */
614 | setsockopt(temp->sock, IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, (char *)&mreq, sizeof(mreq));
615 |
616 | //LOGGER_DEBUG(res < 0 ? "Failed to activate local multicast membership. (%u, %s)" :
617 | // "Local multicast group FF02::1 joined successfully", errno, strerror(errno) );
618 | }
619 |
620 | /* a hanging program or a different user might block the standard port;
621 | * as long as it isn't a parameter coming from the commandline,
622 | * try a few ports after it, to see if we can find a "free" one
623 | *
624 | * if we go on without binding, the first sendto() automatically binds to
625 | * a free port chosen by the system (i.e. anything from 1024 to 65535)
626 | *
627 | * returning NULL after bind fails has both advantages and disadvantages:
628 | * advantage:
629 | * we can rely on getting the port in the range 33445..33450, which
630 | * enables us to tell joe user to open their firewall to a small range
631 | *
632 | * disadvantage:
633 | * some clients might not test return of tox_new(), blindly assuming that
634 | * it worked ok (which it did previously without a successful bind)
635 | */
636 | uint16_t port_to_try = port_from;
637 | *portptr = htons(port_to_try);
638 | int tries;
639 |
640 | for (tries = port_from; tries <= port_to; tries++) {
641 | int res = bind(temp->sock, (struct sockaddr *)&addr, addrsize);
642 |
643 | if (!res) {
644 | temp->port = *portptr;
645 |
646 | //LOGGER_DEBUG("Bound successfully to %s:%u", ip_ntoa(&ip), ntohs(temp->port));
647 |
648 | /* errno isn't reset on success, only set on failure, the failed
649 | * binds with parallel clients yield a -EPERM to the outside if
650 | * errno isn't cleared here */
651 | if (tries > 0)
652 | errno = 0;
653 |
654 | if (error)
655 | *error = 0;
656 |
657 | return temp;
658 | }
659 |
660 | port_to_try++;
661 |
662 | if (port_to_try > port_to)
663 | port_to_try = port_from;
664 |
665 | *portptr = htons(port_to_try);
666 | }
667 |
668 | //LOGGER_ERROR("Failed to bind socket: %u, %s IP: %s port_from: %u port_to: %u", errno, strerror(errno),
669 | // ip_ntoa(&ip), port_from, port_to);
670 |
671 | kill_networking(temp);
672 |
673 | if (error)
674 | *error = 1;
675 |
676 | return NULL;
677 | }
678 |
679 | /* Function to cleanup networking stuff. */
680 | void kill_networking(Networking_Core *net)
681 | {
682 | if (net->family != 0) /* Socket not initialized */
683 | kill_sock(net->sock);
684 |
685 | free(net);
686 | return;
687 | }
688 |
689 | /* ip_equal
690 | * compares two IPAny structures
691 | * unset means unequal
692 | *
693 | * returns 0 when not equal or when uninitialized
694 | */
695 | int ip_equal(const IP *a, const IP *b)
696 | {
697 | if (!a || !b)
698 | return 0;
699 |
700 | /* same family */
701 | if (a->family == b->family) {
702 | if (a->family == AF_INET)
703 | return (a->ip4.in_addr.s_addr == b->ip4.in_addr.s_addr);
704 | else if (a->family == AF_INET6)
705 | return a->ip6.uint64[0] == b->ip6.uint64[0] && a->ip6.uint64[1] == b->ip6.uint64[1];
706 | else
707 | return 0;
708 | }
709 |
710 | /* different family: check on the IPv6 one if it is the IPv4 one embedded */
711 | if ((a->family == AF_INET) && (b->family == AF_INET6)) {
712 | if (IPV6_IPV4_IN_V6(b->ip6))
713 | return (a->ip4.in_addr.s_addr == b->ip6.uint32[3]);
714 | } else if ((a->family == AF_INET6) && (b->family == AF_INET)) {
715 | if (IPV6_IPV4_IN_V6(a->ip6))
716 | return (a->ip6.uint32[3] == b->ip4.in_addr.s_addr);
717 | }
718 |
719 | return 0;
720 | }
721 |
722 | /* ipport_equal
723 | * compares two IPAny_Port structures
724 | * unset means unequal
725 | *
726 | * returns 0 when not equal or when uninitialized
727 | */
728 | int ipport_equal(const IP_Port *a, const IP_Port *b)
729 | {
730 | if (!a || !b)
731 | return 0;
732 |
733 | if (!a->port || (a->port != b->port))
734 | return 0;
735 |
736 | return ip_equal(&a->ip, &b->ip);
737 | }
738 |
739 | /* nulls out ip */
740 | void ip_reset(IP *ip)
741 | {
742 | if (!ip)
743 | return;
744 |
745 | memset(ip, 0, sizeof(IP));
746 | }
747 |
748 | /* nulls out ip, sets family according to flag */
749 | void ip_init(IP *ip, uint8_t ipv6enabled)
750 | {
751 | if (!ip)
752 | return;
753 |
754 | memset(ip, 0, sizeof(IP));
755 | ip->family = ipv6enabled ? AF_INET6 : AF_INET;
756 | }
757 |
758 | /* checks if ip is valid */
759 | int ip_isset(const IP *ip)
760 | {
761 | if (!ip)
762 | return 0;
763 |
764 | return (ip->family != 0);
765 | }
766 |
767 | /* checks if ip is valid */
768 | int ipport_isset(const IP_Port *ipport)
769 | {
770 | if (!ipport)
771 | return 0;
772 |
773 | if (!ipport->port)
774 | return 0;
775 |
776 | return ip_isset(&ipport->ip);
777 | }
778 |
779 | /* copies an ip structure (careful about direction!) */
780 | void ip_copy(IP *target, const IP *source)
781 | {
782 | if (!source || !target)
783 | return;
784 |
785 | memcpy(target, source, sizeof(IP));
786 | }
787 |
788 | /* copies an ip_port structure (careful about direction!) */
789 | void ipport_copy(IP_Port *target, const IP_Port *source)
790 | {
791 | if (!source || !target)
792 | return;
793 |
794 | memcpy(target, source, sizeof(IP_Port));
795 | };
796 |
797 | /* ip_ntoa
798 | * converts ip into a string
799 | * uses a static buffer, so mustn't used multiple times in the same output
800 | *
801 | * IPv6 addresses are enclosed into square brackets, i.e. "[IPv6]"
802 | * writes error message into the buffer on error
803 | */
804 | /* there would be INET6_ADDRSTRLEN, but it might be too short for the error message */
805 | static char addresstext[96];
806 | const char *ip_ntoa(const IP *ip)
807 | {
808 | if (ip) {
809 | if (ip->family == AF_INET) {
810 | /* returns standard quad-dotted notation */
811 | struct in_addr *addr = (struct in_addr *)&ip->ip4;
812 |
813 | addresstext[0] = 0;
814 | inet_ntop(ip->family, addr, addresstext, sizeof(addresstext));
815 | } else if (ip->family == AF_INET6) {
816 | /* returns hex-groups enclosed into square brackets */
817 | struct in6_addr *addr = (struct in6_addr *)&ip->ip6;
818 |
819 | addresstext[0] = '[';
820 | inet_ntop(ip->family, addr, &addresstext[1], sizeof(addresstext) - 3);
821 | size_t len = strlen(addresstext);
822 | addresstext[len] = ']';
823 | addresstext[len + 1] = 0;
824 | } else
825 | snprintf(addresstext, sizeof(addresstext), "(IP invalid, family %u)", ip->family);
826 | } else
827 | snprintf(addresstext, sizeof(addresstext), "(IP invalid: NULL)");
828 |
829 | /* brute force protection against lacking termination */
830 | addresstext[sizeof(addresstext) - 1] = 0;
831 | return addresstext;
832 | }
833 |
834 | /*
835 | * ip_parse_addr
836 | * parses IP structure into an address string
837 | *
838 | * input
839 | * ip: ip of AF_INET or AF_INET6 families
840 | * length: length of the address buffer
841 | * Must be at least INET_ADDRSTRLEN for AF_INET
842 | * and INET6_ADDRSTRLEN for AF_INET6
843 | *
844 | * output
845 | * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
846 | *
847 | * returns 1 on success, 0 on failure
848 | */
849 | int ip_parse_addr(const IP *ip, char *address, size_t length)
850 | {
851 | if (!address || !ip) {
852 | return 0;
853 | }
854 |
855 | if (ip->family == AF_INET) {
856 | struct in_addr *addr = (struct in_addr *)&ip->ip4;
857 | return inet_ntop(ip->family, addr, address, length) != NULL;
858 | } else if (ip->family == AF_INET6) {
859 | struct in6_addr *addr = (struct in6_addr *)&ip->ip6;
860 | return inet_ntop(ip->family, addr, address, length) != NULL;
861 | }
862 |
863 | return 0;
864 | }
865 |
866 | /*
867 | * addr_parse_ip
868 | * directly parses the input into an IP structure
869 | * tries IPv4 first, then IPv6
870 | *
871 | * input
872 | * address: dotted notation (IPv4: quad, IPv6: 16) or colon notation (IPv6)
873 | *
874 | * output
875 | * IP: family and the value is set on success
876 | *
877 | * returns 1 on success, 0 on failure
878 | */
879 | int addr_parse_ip(const char *address, IP *to)
880 | {
881 | if (!address || !to)
882 | return 0;
883 |
884 | struct in_addr addr4;
885 |
886 | if (1 == inet_pton(AF_INET, address, &addr4)) {
887 | to->family = AF_INET;
888 | to->ip4.in_addr = addr4;
889 | return 1;
890 | }
891 |
892 | struct in6_addr addr6;
893 |
894 | if (1 == inet_pton(AF_INET6, address, &addr6)) {
895 | to->family = AF_INET6;
896 | to->ip6.in6_addr = addr6;
897 | return 1;
898 | }
899 |
900 | return 0;
901 | }
902 |
903 | /*
904 | * addr_resolve():
905 | * uses getaddrinfo to resolve an address into an IP address
906 | * uses the first IPv4/IPv6 addresses returned by getaddrinfo
907 | *
908 | * input
909 | * address: a hostname (or something parseable to an IP address)
910 | * to: to.family MUST be initialized, either set to a specific IP version
911 | * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
912 | * IP versions are acceptable
913 | * extra can be NULL and is only set in special circumstances, see returns
914 | *
915 | * returns in *to a valid IPAny (v4/v6),
916 | * prefers v6 if ip.family was AF_UNSPEC and both available
917 | * returns in *extra an IPv4 address, if family was AF_UNSPEC and *to is AF_INET6
918 | * returns 0 on failure
919 | */
920 | int addr_resolve(const char *address, IP *to, IP *extra)
921 | {
922 | if (!address || !to)
923 | return 0;
924 |
925 | sa_family_t family = to->family;
926 |
927 | struct addrinfo *server = NULL;
928 | struct addrinfo *walker = NULL;
929 | struct addrinfo hints;
930 | int rc;
931 |
932 | memset(&hints, 0, sizeof(hints));
933 | hints.ai_family = family;
934 | hints.ai_socktype = SOCK_DGRAM; // type of socket Tox uses.
935 |
936 | if (networking_at_startup() != 0)
937 | return 0;
938 |
939 | rc = getaddrinfo(address, NULL, &hints, &server);
940 |
941 | // Lookup failed.
942 | if (rc != 0) {
943 | return 0;
944 | }
945 |
946 | IP4 ip4;
947 | memset(&ip4, 0, sizeof(ip4));
948 | IP6 ip6;
949 | memset(&ip6, 0, sizeof(ip6));
950 |
951 | for (walker = server; (walker != NULL) && (rc != 3); walker = walker->ai_next) {
952 | switch (walker->ai_family) {
953 | case AF_INET:
954 | if (walker->ai_family == family) { /* AF_INET requested, done */
955 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
956 | to->ip4.in_addr = addr->sin_addr;
957 | rc = 3;
958 | } else if (!(rc & 1)) { /* AF_UNSPEC requested, store away */
959 | struct sockaddr_in *addr = (struct sockaddr_in *)walker->ai_addr;
960 | ip4.in_addr = addr->sin_addr;
961 | rc |= 1;
962 | }
963 |
964 | break; /* switch */
965 |
966 | case AF_INET6:
967 | if (walker->ai_family == family) { /* AF_INET6 requested, done */
968 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
969 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
970 | to->ip6.in6_addr = addr->sin6_addr;
971 | rc = 3;
972 | }
973 | } else if (!(rc & 2)) { /* AF_UNSPEC requested, store away */
974 | if (walker->ai_addrlen == sizeof(struct sockaddr_in6)) {
975 | struct sockaddr_in6 *addr = (struct sockaddr_in6 *)walker->ai_addr;
976 | ip6.in6_addr = addr->sin6_addr;
977 | rc |= 2;
978 | }
979 | }
980 |
981 | break; /* switch */
982 | }
983 | }
984 |
985 | if (to->family == AF_UNSPEC) {
986 | if (rc & 2) {
987 | to->family = AF_INET6;
988 | to->ip6 = ip6;
989 |
990 | if ((rc & 1) && (extra != NULL)) {
991 | extra->family = AF_INET;
992 | extra->ip4 = ip4;
993 | }
994 | } else if (rc & 1) {
995 | to->family = AF_INET;
996 | to->ip4 = ip4;
997 | } else
998 | rc = 0;
999 | }
1000 |
1001 | freeaddrinfo(server);
1002 | return rc;
1003 | }
1004 |
1005 | /*
1006 | * addr_resolve_or_parse_ip
1007 | * resolves string into an IP address
1008 | *
1009 | * address: a hostname (or something parseable to an IP address)
1010 | * to: to.family MUST be initialized, either set to a specific IP version
1011 | * (AF_INET/AF_INET6) or to the unspecified AF_UNSPEC (= 0), if both
1012 | * IP versions are acceptable
1013 | * extra can be NULL and is only set in special circumstances, see returns
1014 | *
1015 | * returns in *tro a matching address (IPv6 or IPv4)
1016 | * returns in *extra, if not NULL, an IPv4 address, if to->family was AF_UNSPEC
1017 | * returns 1 on success
1018 | * returns 0 on failure
1019 | */
1020 | int addr_resolve_or_parse_ip(const char *address, IP *to, IP *extra)
1021 | {
1022 | if (!addr_resolve(address, to, extra))
1023 | if (!addr_parse_ip(address, to))
1024 | return 0;
1025 |
1026 | return 1;
1027 | }
1028 |
--------------------------------------------------------------------------------