├── 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 | ![Toxcoin](https://raw.github.com/irungentoo/toxcoin/master/logo/toxcoin.png "All of our startup money was spent on this logo.") 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 | --------------------------------------------------------------------------------