14 #include <event2/util.h>
17 #include "salsa20_random.h"
18 #include "randombytes.h"
22 dnscrypt_response_header_size(void)
24 return sizeof DNSCRYPT_MAGIC_RESPONSE
- 1U
25 + crypto_box_NONCEBYTES
+ crypto_box_MACBYTES
;
29 dnscrypt_query_header_size(void)
31 return DNSCRYPT_MAGIC_QUERY_LEN
32 + crypto_box_PUBLICKEYBYTES
+ crypto_box_HALF_NONCEBYTES
33 + crypto_box_MACBYTES
;
37 dnscrypt_memcmp(const void * const b1_
, const void * const b2_
,
40 const uint8_t *b1
= b1_
;
41 const uint8_t *b2
= b2_
;
42 size_t i
= (size_t) 0U;
43 uint8_t d
= (uint8_t) 0U;
45 assert(size
> (size_t) 0U);
54 dnscrypt_cmp_client_nonce(const uint8_t client_nonce
[crypto_box_HALF_NONCEBYTES
],
55 const uint8_t * const buf
, const size_t len
)
57 const size_t client_nonce_offset
= sizeof DNSCRYPT_MAGIC_RESPONSE
- 1U;
59 if (len
< client_nonce_offset
+ crypto_box_HALF_NONCEBYTES
||
60 dnscrypt_memcmp(client_nonce
, buf
+ client_nonce_offset
,
61 crypto_box_HALF_NONCEBYTES
) != 0) {
68 dnscrypt_pad(uint8_t *buf
, const size_t len
, const size_t max_len
)
70 uint8_t *buf_padding_area
= buf
+ len
;
71 size_t padded_len
, padding_len
;
73 if (max_len
< len
+ DNSCRYPT_MIN_PAD_LEN
) {
76 padded_len
= len
+ DNSCRYPT_MIN_PAD_LEN
+ salsa20_random_uniform
77 ((uint32_t) (max_len
- len
- DNSCRYPT_MIN_PAD_LEN
+ 1U));
78 padded_len
+= DNSCRYPT_BLOCK_SIZE
- padded_len
% DNSCRYPT_BLOCK_SIZE
;
79 if (padded_len
> max_len
) {
82 assert(padded_len
>= len
);
83 padding_len
= padded_len
- len
;
84 memset(buf_padding_area
, 0, padding_len
);
85 *buf_padding_area
= 0x80;
86 assert(max_len
>= padded_len
);
92 randombytes(unsigned char * const buf
, const unsigned long long buf_len
)
94 assert(buf_len
<= SIZE_MAX
);
95 salsa20_random_buf(buf
, buf_len
);
99 dnscrypt_key_to_fingerprint(char fingerprint
[80U], const uint8_t * const key
)
101 const size_t fingerprint_size
= 80U;
102 size_t fingerprint_pos
= (size_t) 0U;
103 size_t key_pos
= (size_t) 0U;
105 COMPILER_ASSERT(crypto_box_PUBLICKEYBYTES
== 32U);
106 COMPILER_ASSERT(crypto_box_SECRETKEYBYTES
== 32U);
108 assert(fingerprint_size
> fingerprint_pos
);
109 evutil_snprintf(&fingerprint
[fingerprint_pos
],
110 fingerprint_size
- fingerprint_pos
, "%02X%02X",
111 key
[key_pos
], key
[key_pos
+ 1U]);
113 if (key_pos
>= crypto_box_PUBLICKEYBYTES
) {
116 fingerprint
[fingerprint_pos
+ 4U] = ':';
117 fingerprint_pos
+= 5U;
122 _dnscrypt_parse_char(uint8_t key
[crypto_box_PUBLICKEYBYTES
],
123 size_t * const key_pos_p
, int * const state_p
,
124 const int c
, uint8_t * const val_p
)
131 if (isspace(c
) || (c
== ':' && *state_p
== 0)) {
141 c_val
= (uint8_t) ((c
>= '0' && c
<= '9') ? c
- '0' : c
- 'a' + 10);
144 *val_p
= c_val
* 16U;
148 key
[(*key_pos_p
)++] = *val_p
;
149 if (*key_pos_p
>= crypto_box_PUBLICKEYBYTES
) {
164 dnscrypt_fingerprint_to_key(const char * const fingerprint
,
165 uint8_t key
[crypto_box_PUBLICKEYBYTES
])
167 const char *p
= fingerprint
;
168 size_t key_pos
= (size_t) 0U;
174 if (fingerprint
== NULL
) {
177 while ((c
= tolower((int) (unsigned char) *p
)) != 0) {
178 ret
= _dnscrypt_parse_char(key
, &key_pos
, &state
, c
, &val
);