dnscrypto-proxy: Update to release 1.3.0
[tomato.git] / release / src / router / dnscrypt / src / proxy / dnscrypt_client.c
blobf01eece8dde522763915fce00530561e60c9ced6
2 #include <config.h>
3 #include <sys/types.h>
4 #include <sys/time.h>
5 #ifdef _WIN32
6 # include <winsock2.h>
7 #else
8 # include <arpa/inet.h>
9 #endif
11 #include <assert.h>
12 #include <stdint.h>
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <string.h>
17 #include <event2/event.h>
19 #include "dnscrypt.h"
20 #include "dnscrypt_client.h"
21 #include "sodium.h"
22 #include "utils.h"
24 static void
25 dnscrypt_make_client_nonce(DNSCryptClient * const client,
26 uint8_t client_nonce[crypto_box_HALF_NONCEBYTES])
28 uint64_t ts;
29 uint64_t tsn;
30 uint32_t suffix;
32 ts = dnscrypt_hrtime();
33 if (ts <= client->nonce_ts_last) {
34 ts = client->nonce_ts_last + (uint64_t) 1U;
36 client->nonce_ts_last = ts;
38 tsn = (ts << 10) | (randombytes_random() & 0x3ff);
39 #ifdef WORDS_BIGENDIAN
40 tsn = (((uint64_t) htonl((uint32_t) tsn)) << 32) |
41 htonl((uint32_t) (tsn >> 32));
42 #endif
43 COMPILER_ASSERT(crypto_box_HALF_NONCEBYTES == 12U);
44 memcpy(client_nonce, &tsn, 8U);
45 suffix = randombytes_random();
46 memcpy(client_nonce + 8U, &suffix, 4U);
49 // 8 bytes: magic_query
50 // 32 bytes: the client's DNSCurve public key (crypto_box_PUBLICKEYBYTES)
51 // 12 bytes: a client-selected nonce for this packet (crypto_box_NONCEBYTES / 2)
52 // 16 bytes: Poly1305 MAC (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
54 ssize_t
55 dnscrypt_client_curve(DNSCryptClient * const client,
56 uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
57 uint8_t *buf, size_t len, const size_t max_len)
59 uint8_t nonce[crypto_box_NONCEBYTES];
60 uint8_t *boxed;
62 #if crypto_box_MACBYTES > 8U + crypto_box_NONCEBYTES
63 # error Cannot curve in-place
64 #endif
65 if (max_len < len || max_len - len < dnscrypt_query_header_size()) {
66 return (ssize_t) -1;
68 assert(max_len > dnscrypt_query_header_size());
69 boxed = buf + sizeof client->magic_query
70 + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES;
71 memmove(boxed + crypto_box_MACBYTES, buf, len);
72 len = dnscrypt_pad(boxed + crypto_box_MACBYTES, len,
73 max_len - dnscrypt_query_header_size());
74 memset(boxed - crypto_box_BOXZEROBYTES, 0, crypto_box_ZEROBYTES);
75 dnscrypt_make_client_nonce(client, nonce);
76 memcpy(client_nonce, nonce, crypto_box_HALF_NONCEBYTES);
77 memset(nonce + crypto_box_HALF_NONCEBYTES, 0, crypto_box_HALF_NONCEBYTES);
79 if (crypto_box_afternm
80 (boxed - crypto_box_BOXZEROBYTES, boxed - crypto_box_BOXZEROBYTES,
81 len + crypto_box_ZEROBYTES, nonce, client->nmkey) != 0) {
82 return (ssize_t) -1;
84 memcpy(buf, client->magic_query, sizeof client->magic_query);
85 memcpy(buf + sizeof client->magic_query, client->publickey,
86 crypto_box_PUBLICKEYBYTES);
87 memcpy(buf + sizeof client->magic_query + crypto_box_PUBLICKEYBYTES,
88 nonce, crypto_box_HALF_NONCEBYTES);
90 return (ssize_t) (len + dnscrypt_query_header_size());
93 // 8 bytes: the string r6fnvWJ8 (DNSCRYPT_MAGIC_RESPONSE)
94 // 12 bytes: the client's nonce (crypto_box_NONCEBYTES / 2)
95 // 12 bytes: a server-selected nonce extension (crypto_box_NONCEBYTES / 2)
96 // 16 bytes: Poly1305 MAC (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
98 #define DNSCRYPT_SERVER_BOX_OFFSET \
99 (sizeof DNSCRYPT_MAGIC_RESPONSE - 1U + crypto_box_NONCEBYTES)
102 dnscrypt_client_uncurve(const DNSCryptClient * const client,
103 const uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
104 uint8_t * const buf, size_t * const lenp)
106 uint8_t nonce[crypto_box_NONCEBYTES];
107 size_t len = *lenp;
109 if (len <= dnscrypt_response_header_size() ||
110 memcmp(buf, DNSCRYPT_MAGIC_RESPONSE,
111 sizeof DNSCRYPT_MAGIC_RESPONSE - 1U)) {
112 return 1;
114 if (dnscrypt_cmp_client_nonce(client_nonce, buf, len) != 0) {
115 return -1;
117 memcpy(nonce, buf + sizeof DNSCRYPT_MAGIC_RESPONSE - 1U,
118 crypto_box_NONCEBYTES);
119 memset(buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES, 0,
120 crypto_box_BOXZEROBYTES);
121 if (crypto_box_open_afternm
122 (buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES,
123 buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES,
124 len - DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES,
125 nonce, client->nmkey)) {
126 return -1;
128 sodium_memzero(nonce, sizeof nonce);
129 assert(len >= DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES);
130 while (len > 0U && buf[--len] == 0U) { }
131 if (buf[len] != 0x80) {
132 return -1;
134 *lenp = len - (DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES);
135 memmove(buf,
136 buf + DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES, *lenp);
137 return 0;
141 dnscrypt_client_init_magic_query(DNSCryptClient * const client,
142 const uint8_t magic_query[DNSCRYPT_MAGIC_QUERY_LEN])
144 COMPILER_ASSERT(DNSCRYPT_MAGIC_QUERY_LEN == sizeof client->magic_query);
145 memcpy(client->magic_query, magic_query, sizeof client->magic_query);
147 return 0;
151 dnscrypt_client_init_nmkey(DNSCryptClient * const client,
152 const uint8_t server_publickey[crypto_box_PUBLICKEYBYTES])
154 #if crypto_box_BEFORENMBYTES != crypto_box_PUBLICKEYBYTES
155 # error crypto_box_BEFORENMBYTES != crypto_box_PUBLICKEYBYTES
156 #endif
157 memcpy(client->nmkey, server_publickey, crypto_box_PUBLICKEYBYTES);
158 crypto_box_beforenm(client->nmkey, client->nmkey, client->secretkey);
160 return 0;
164 dnscrypt_client_wipe_secretkey(DNSCryptClient * const client)
166 randombytes_buf(client->secretkey, crypto_box_SECRETKEYBYTES);
168 return 0;
172 dnscrypt_client_init_with_key_pair(DNSCryptClient * const client,
173 const uint8_t client_publickey[crypto_box_PUBLICKEYBYTES],
174 const uint8_t client_secretkey[crypto_box_SECRETKEYBYTES])
176 memcpy(client->publickey, client_publickey, crypto_box_PUBLICKEYBYTES);
177 memcpy(client->secretkey, client_secretkey, crypto_box_SECRETKEYBYTES);
179 return 0;
183 dnscrypt_client_create_key_pair(DNSCryptClient * const client,
184 uint8_t client_publickey[crypto_box_PUBLICKEYBYTES],
185 uint8_t client_secretkey[crypto_box_SECRETKEYBYTES])
187 (void) client;
188 crypto_box_keypair(client_publickey, client_secretkey);
189 randombytes_stir();
191 return 0;
195 dnscrypt_client_init_with_new_key_pair(DNSCryptClient * const client)
197 uint8_t client_publickey[crypto_box_PUBLICKEYBYTES];
198 uint8_t client_secretkey[crypto_box_SECRETKEYBYTES];
200 dnscrypt_client_create_key_pair(client,
201 client_publickey, client_secretkey);
202 dnscrypt_client_init_with_key_pair(client,
203 client_publickey, client_secretkey);
205 return 0;