8 # include <arpa/inet.h>
17 #include <event2/event.h>
21 #include "dnscrypt_client.h"
25 dnscrypt_make_client_nonce(DNSCryptClient
* const client
,
26 uint8_t client_nonce
[crypto_box_HALF_NONCEBYTES
])
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));
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)
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
];
67 #if crypto_box_MACBYTES > 8U + crypto_box_NONCEBYTES
68 # error Cannot curve in-place
70 if (max_len
< len
|| max_len
- len
< dnscrypt_query_header_size()) {
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
,
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
);
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
];
137 if (len
<= dnscrypt_response_header_size() ||
138 memcmp(buf
, DNSCRYPT_MAGIC_RESPONSE
,
139 sizeof DNSCRYPT_MAGIC_RESPONSE
- 1U)) {
142 if (dnscrypt_cmp_client_nonce(client_nonce
, buf
, len
) != 0) {
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
);
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
);
173 assert(len
>= DNSCRYPT_SERVER_BOX_OFFSET
+ crypto_box_BOXZEROBYTES
);
174 while (len
> 0U && buf
[--len
] == 0U) { }
175 if (buf
[len
] != 0x80) {
178 *lenp
= len
- (DNSCRYPT_SERVER_BOX_OFFSET
+ crypto_box_BOXZEROBYTES
);
180 buf
+ DNSCRYPT_SERVER_BOX_OFFSET
+ crypto_box_BOXZEROBYTES
, *lenp
);
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
);
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
201 if (client
->ephemeral_keys
== 0) {
202 crypto_box_beforenm(client
->nmkey
, resolver_publickey
,
205 memcpy(client
->publickey
, resolver_publickey
, sizeof client
->publickey
);
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
);
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
);
232 dnscrypt_client_init_with_client_key(DNSCryptClient
* const client
)
234 if (crypto_scalarmult_base(client
->publickey
, client
->secretkey
) != 0) {