dnscrypt-proxy 1.6.0
[tomato.git] / release / src / router / dnscrypt / src / proxy / dnscrypt_client.c
blobba85700bd3d10305b584c01952328a8d465b0f80
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>
18 #include <sodium.h>
20 #include "dnscrypt.h"
21 #include "dnscrypt_client.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 eph_publickey[crypto_box_PUBLICKEYBYTES];
60 uint8_t eph_secretkey[crypto_box_SECRETKEYBYTES];
61 uint8_t eph_nonce[crypto_stream_NONCEBYTES];
62 uint8_t nonce[crypto_box_NONCEBYTES];
63 uint8_t *publickey;
64 uint8_t *boxed;
65 int res;
67 #if crypto_box_MACBYTES > 8U + crypto_box_NONCEBYTES
68 # error Cannot curve in-place
69 #endif
70 if (max_len < len || max_len - len < dnscrypt_query_header_size()) {
71 return (ssize_t) -1;
73 assert(max_len > dnscrypt_query_header_size());
74 boxed = buf + sizeof client->magic_query
75 + crypto_box_PUBLICKEYBYTES + crypto_box_HALF_NONCEBYTES;
76 memmove(boxed + crypto_box_MACBYTES, buf, len);
77 len = dnscrypt_pad(boxed + crypto_box_MACBYTES, len,
78 max_len - dnscrypt_query_header_size());
79 memset(boxed - crypto_box_BOXZEROBYTES, 0, crypto_box_ZEROBYTES);
80 dnscrypt_make_client_nonce(client, nonce);
81 memcpy(client_nonce, nonce, crypto_box_HALF_NONCEBYTES);
82 memset(nonce + crypto_box_HALF_NONCEBYTES, 0, crypto_box_HALF_NONCEBYTES);
84 if (client->ephemeral_keys == 0) {
85 publickey = client->publickey;
86 res = crypto_box_afternm(boxed - crypto_box_BOXZEROBYTES,
87 boxed - crypto_box_BOXZEROBYTES,
88 len + crypto_box_ZEROBYTES, nonce,
89 client->nmkey);
90 } else {
91 COMPILER_ASSERT(crypto_box_HALF_NONCEBYTES < sizeof eph_nonce);
92 memcpy(eph_nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
93 memcpy(eph_nonce + crypto_box_HALF_NONCEBYTES, client->nonce_pad,
94 crypto_box_HALF_NONCEBYTES);
95 crypto_stream(eph_secretkey, sizeof eph_secretkey,
96 eph_nonce, client->secretkey);
97 crypto_scalarmult_base(eph_publickey, eph_secretkey);
98 publickey = eph_publickey;
99 res = crypto_box(boxed - crypto_box_BOXZEROBYTES,
100 boxed - crypto_box_BOXZEROBYTES,
101 len + crypto_box_ZEROBYTES, nonce,
102 client->publickey, eph_secretkey);
103 sodium_memzero(eph_secretkey, sizeof eph_secretkey);
105 if (res != 0) {
106 return (ssize_t) -1;
108 memcpy(buf, client->magic_query, sizeof client->magic_query);
109 memcpy(buf + sizeof client->magic_query, publickey,
110 crypto_box_PUBLICKEYBYTES);
111 memcpy(buf + sizeof client->magic_query + crypto_box_PUBLICKEYBYTES,
112 nonce, crypto_box_HALF_NONCEBYTES);
114 return (ssize_t) (len + dnscrypt_query_header_size());
117 // 8 bytes: the string r6fnvWJ8 (DNSCRYPT_MAGIC_RESPONSE)
118 // 12 bytes: the client's nonce (crypto_box_NONCEBYTES / 2)
119 // 12 bytes: a server-selected nonce extension (crypto_box_NONCEBYTES / 2)
120 // 16 bytes: Poly1305 MAC (crypto_box_ZEROBYTES - crypto_box_BOXZEROBYTES)
122 #define DNSCRYPT_SERVER_BOX_OFFSET \
123 (sizeof DNSCRYPT_MAGIC_RESPONSE - 1U + crypto_box_NONCEBYTES)
126 dnscrypt_client_uncurve(const DNSCryptClient * const client,
127 const uint8_t client_nonce[crypto_box_HALF_NONCEBYTES],
128 uint8_t * const buf, size_t * const lenp)
130 uint8_t eph_publickey[crypto_box_PUBLICKEYBYTES];
131 uint8_t eph_secretkey[crypto_box_SECRETKEYBYTES];
132 uint8_t eph_nonce[crypto_stream_NONCEBYTES];
133 uint8_t nonce[crypto_box_NONCEBYTES];
134 size_t len = *lenp;
135 int res;
137 if (len <= dnscrypt_response_header_size() ||
138 memcmp(buf, DNSCRYPT_MAGIC_RESPONSE,
139 sizeof DNSCRYPT_MAGIC_RESPONSE - 1U)) {
140 return 1;
142 if (dnscrypt_cmp_client_nonce(client_nonce, buf, len) != 0) {
143 return -1;
145 memcpy(nonce, buf + sizeof DNSCRYPT_MAGIC_RESPONSE - 1U,
146 crypto_box_NONCEBYTES);
147 memset(buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES, 0,
148 crypto_box_BOXZEROBYTES);
149 if (client->ephemeral_keys == 0) {
150 res = crypto_box_open_afternm
151 (buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES,
152 buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES,
153 len - DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES,
154 nonce, client->nmkey);
155 } else {
156 memcpy(eph_nonce, client_nonce, crypto_box_HALF_NONCEBYTES);
157 memcpy(eph_nonce + crypto_box_HALF_NONCEBYTES, client->nonce_pad,
158 crypto_box_HALF_NONCEBYTES);
159 crypto_stream(eph_secretkey, sizeof eph_secretkey,
160 eph_nonce, client->secretkey);
161 crypto_scalarmult_base(eph_publickey, eph_secretkey);
162 res = crypto_box_open
163 (buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES,
164 buf + DNSCRYPT_SERVER_BOX_OFFSET - crypto_box_BOXZEROBYTES,
165 len - DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES,
166 nonce, client->publickey, eph_secretkey);
167 sodium_memzero(eph_secretkey, sizeof eph_secretkey);
169 sodium_memzero(nonce, sizeof nonce);
170 if (res != 0) {
171 return -1;
173 assert(len >= DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES);
174 while (len > 0U && buf[--len] == 0U) { }
175 if (buf[len] != 0x80) {
176 return -1;
178 *lenp = len - (DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES);
179 memmove(buf,
180 buf + DNSCRYPT_SERVER_BOX_OFFSET + crypto_box_BOXZEROBYTES, *lenp);
181 return 0;
185 dnscrypt_client_init_magic_query(DNSCryptClient * const client,
186 const uint8_t magic_query[DNSCRYPT_MAGIC_QUERY_LEN])
188 COMPILER_ASSERT(DNSCRYPT_MAGIC_QUERY_LEN == sizeof client->magic_query);
189 memcpy(client->magic_query, magic_query, sizeof client->magic_query);
191 return 0;
195 dnscrypt_client_init_resolver_publickey(DNSCryptClient * const client,
196 const uint8_t resolver_publickey[crypto_box_PUBLICKEYBYTES])
198 #if crypto_box_BEFORENMBYTES != crypto_box_PUBLICKEYBYTES
199 # error crypto_box_BEFORENMBYTES != crypto_box_PUBLICKEYBYTES
200 #endif
201 if (client->ephemeral_keys == 0) {
202 crypto_box_beforenm(client->nmkey, resolver_publickey,
203 client->secretkey);
204 } else {
205 memcpy(client->publickey, resolver_publickey, sizeof client->publickey);
207 return 0;
211 dnscrypt_client_init_with_new_session_key(DNSCryptClient * const client)
213 assert(client->ephemeral_keys != 0);
214 randombytes_buf(client->nonce_pad, sizeof client->nonce_pad);
215 randombytes_buf(client->secretkey, sizeof client->secretkey);
216 randombytes_stir();
218 return 0;
222 dnscrypt_client_init_with_new_key_pair(DNSCryptClient * const client)
224 assert(client->ephemeral_keys == 0);
225 crypto_box_keypair(client->publickey, client->secretkey);
226 randombytes_stir();
228 return 0;
232 dnscrypt_client_init_with_client_key(DNSCryptClient * const client)
234 if (crypto_scalarmult_base(client->publickey, client->secretkey) != 0) {
235 return -1;
237 return 0;