8 # include <arpa/inet.h>
17 #include <event2/event.h>
20 #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 nonce
[crypto_box_NONCEBYTES
];
62 #if crypto_box_MACBYTES > 8U + crypto_box_NONCEBYTES
63 # error Cannot curve in-place
65 if (max_len
< len
|| max_len
- len
< dnscrypt_query_header_size()) {
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) {
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
];
109 if (len
<= dnscrypt_response_header_size() ||
110 memcmp(buf
, DNSCRYPT_MAGIC_RESPONSE
,
111 sizeof DNSCRYPT_MAGIC_RESPONSE
- 1U)) {
114 if (dnscrypt_cmp_client_nonce(client_nonce
, buf
, len
) != 0) {
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
)) {
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) {
134 *lenp
= len
- (DNSCRYPT_SERVER_BOX_OFFSET
+ crypto_box_BOXZEROBYTES
);
136 buf
+ DNSCRYPT_SERVER_BOX_OFFSET
+ crypto_box_BOXZEROBYTES
, *lenp
);
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
);
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
157 memcpy(client
->nmkey
, server_publickey
, crypto_box_PUBLICKEYBYTES
);
158 crypto_box_beforenm(client
->nmkey
, client
->nmkey
, client
->secretkey
);
164 dnscrypt_client_wipe_secretkey(DNSCryptClient
* const client
)
166 randombytes_buf(client
->secretkey
, crypto_box_SECRETKEYBYTES
);
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
);
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
])
188 crypto_box_keypair(client_publickey
, client_secretkey
);
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
);