blob: 8e1559ff7ef63990d290f91a7d759c5ec60a1c05 [file] [log] [blame]
Simon Kelley2d765862020-11-12 22:06:07 +00001/* Copyright (c) 2012-2020 Simon Kelley
2
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 dated June, 1991, or
6 (at your option) version 3 dated 29 June, 2007.
7
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with this program. If not, see <http://www.gnu.org/licenses/>.
15*/
16
17
18/* Hash the question section. This is used to safely detect query
19 retransmission and to detect answers to questions we didn't ask, which
20 might be poisoning attacks. Note that we decode the name rather
21 than CRC the raw bytes, since replies might be compressed differently.
22 We ignore case in the names for the same reason.
23
24 The hash used is SHA-256. If we're building with DNSSEC support,
25 we use the Nettle cypto library. If not, we prefer not to
26 add a dependency on Nettle, and use a stand-alone implementaion.
27*/
28
29#include "dnsmasq.h"
30
Simon Kelleya69b0172021-01-24 21:53:28 +000031#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
Simon Kelleye75069f2021-01-22 22:50:25 +000032
33static const struct nettle_hash *hash;
34static void *ctx;
35static unsigned char *digest;
36
37void hash_questions_init(void)
38{
Simon Kelley20295012021-01-24 22:25:13 +000039 if (!(hash = hash_find("sha256")))
Simon Kelleye75069f2021-01-22 22:50:25 +000040 die(_("Failed to create SHA-256 hash object"), NULL, EC_MISC);
Simon Kelley20295012021-01-24 22:25:13 +000041
42 ctx = safe_malloc(hash->context_size);
43 digest = safe_malloc(hash->digest_size);
Simon Kelleye75069f2021-01-22 22:50:25 +000044}
45
Simon Kelley2d765862020-11-12 22:06:07 +000046unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name)
47{
48 int q;
49 unsigned char *p = (unsigned char *)(header+1);
Simon Kelley2d765862020-11-12 22:06:07 +000050
Simon Kelleye75069f2021-01-22 22:50:25 +000051 hash->init(ctx);
52
Simon Kelley2d765862020-11-12 22:06:07 +000053 for (q = ntohs(header->qdcount); q != 0; q--)
54 {
55 char *cp, c;
56
57 if (!extract_name(header, plen, &p, name, 1, 4))
58 break; /* bad packet */
59
60 for (cp = name; (c = *cp); cp++)
61 if (c >= 'A' && c <= 'Z')
62 *cp += 'a' - 'A';
63
64 hash->update(ctx, cp - name, (unsigned char *)name);
65 /* CRC the class and type as well */
66 hash->update(ctx, 4, p);
67
68 p += 4;
69 if (!CHECK_LEN(header, p, plen, 0))
70 break; /* bad packet */
71 }
72
73 hash->digest(ctx, hash->digest_size, digest);
74 return digest;
75}
76
Simon Kelleya69b0172021-01-24 21:53:28 +000077#else /* HAVE_DNSSEC || HAVE_CRYPTOHASH */
Simon Kelley2d765862020-11-12 22:06:07 +000078
79#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
80typedef unsigned char BYTE; // 8-bit byte
81typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
82
83typedef struct {
84 BYTE data[64];
85 WORD datalen;
86 unsigned long long bitlen;
87 WORD state[8];
88} SHA256_CTX;
89
90static void sha256_init(SHA256_CTX *ctx);
91static void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len);
92static void sha256_final(SHA256_CTX *ctx, BYTE hash[]);
93
Simon Kelleye75069f2021-01-22 22:50:25 +000094void hash_questions_init(void)
95{
96}
Simon Kelley2d765862020-11-12 22:06:07 +000097
98unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name)
99{
100 int q;
101 unsigned char *p = (unsigned char *)(header+1);
102 SHA256_CTX ctx;
103 static BYTE digest[SHA256_BLOCK_SIZE];
104
105 sha256_init(&ctx);
106
107 for (q = ntohs(header->qdcount); q != 0; q--)
108 {
109 char *cp, c;
110
111 if (!extract_name(header, plen, &p, name, 1, 4))
112 break; /* bad packet */
113
114 for (cp = name; (c = *cp); cp++)
115 if (c >= 'A' && c <= 'Z')
116 *cp += 'a' - 'A';
117
118 sha256_update(&ctx, (BYTE *)name, cp - name);
119 /* CRC the class and type as well */
120 sha256_update(&ctx, (BYTE *)p, 4);
121
122 p += 4;
123 if (!CHECK_LEN(header, p, plen, 0))
124 break; /* bad packet */
125 }
126
127 sha256_final(&ctx, digest);
128 return (unsigned char *)digest;
129}
130
131/* Code from here onwards comes from https://github.com/B-Con/crypto-algorithms
132 and was written by Brad Conte (brad@bradconte.com), to whom all credit is given.
133
134 This code is in the public domain, and the copyright notice at the head of this
135 file does not apply to it.
136*/
137
138
139/****************************** MACROS ******************************/
140#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
141#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
142
143#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
144#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
145#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
146#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
147#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
148#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
149
150/**************************** VARIABLES *****************************/
151static const WORD k[64] = {
152 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
153 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
154 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
155 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
156 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
157 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
158 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
159 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
160};
161
162/*********************** FUNCTION DEFINITIONS ***********************/
163static void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
164{
165 WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
166
167 for (i = 0, j = 0; i < 16; ++i, j += 4)
168 m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
169 for ( ; i < 64; ++i)
170 m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
171
172 a = ctx->state[0];
173 b = ctx->state[1];
174 c = ctx->state[2];
175 d = ctx->state[3];
176 e = ctx->state[4];
177 f = ctx->state[5];
178 g = ctx->state[6];
179 h = ctx->state[7];
180
181 for (i = 0; i < 64; ++i)
182 {
183 t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
184 t2 = EP0(a) + MAJ(a,b,c);
185 h = g;
186 g = f;
187 f = e;
188 e = d + t1;
189 d = c;
190 c = b;
191 b = a;
192 a = t1 + t2;
193 }
194
195 ctx->state[0] += a;
196 ctx->state[1] += b;
197 ctx->state[2] += c;
198 ctx->state[3] += d;
199 ctx->state[4] += e;
200 ctx->state[5] += f;
201 ctx->state[6] += g;
202 ctx->state[7] += h;
203}
204
205static void sha256_init(SHA256_CTX *ctx)
206{
207 ctx->datalen = 0;
208 ctx->bitlen = 0;
209 ctx->state[0] = 0x6a09e667;
210 ctx->state[1] = 0xbb67ae85;
211 ctx->state[2] = 0x3c6ef372;
212 ctx->state[3] = 0xa54ff53a;
213 ctx->state[4] = 0x510e527f;
214 ctx->state[5] = 0x9b05688c;
215 ctx->state[6] = 0x1f83d9ab;
216 ctx->state[7] = 0x5be0cd19;
217}
218
219static void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
220{
221 WORD i;
222
223 for (i = 0; i < len; ++i)
224 {
225 ctx->data[ctx->datalen] = data[i];
226 ctx->datalen++;
227 if (ctx->datalen == 64) {
228 sha256_transform(ctx, ctx->data);
229 ctx->bitlen += 512;
230 ctx->datalen = 0;
231 }
232 }
233}
234
235static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
236{
237 WORD i;
238
239 i = ctx->datalen;
240
241 // Pad whatever data is left in the buffer.
242 if (ctx->datalen < 56)
243 {
244 ctx->data[i++] = 0x80;
245 while (i < 56)
246 ctx->data[i++] = 0x00;
247 }
248 else
249 {
250 ctx->data[i++] = 0x80;
251 while (i < 64)
252 ctx->data[i++] = 0x00;
253 sha256_transform(ctx, ctx->data);
254 memset(ctx->data, 0, 56);
255 }
256
257 // Append to the padding the total message's length in bits and transform.
258 ctx->bitlen += ctx->datalen * 8;
259 ctx->data[63] = ctx->bitlen;
260 ctx->data[62] = ctx->bitlen >> 8;
261 ctx->data[61] = ctx->bitlen >> 16;
262 ctx->data[60] = ctx->bitlen >> 24;
263 ctx->data[59] = ctx->bitlen >> 32;
264 ctx->data[58] = ctx->bitlen >> 40;
265 ctx->data[57] = ctx->bitlen >> 48;
266 ctx->data[56] = ctx->bitlen >> 56;
267 sha256_transform(ctx, ctx->data);
268
269 // Since this implementation uses little endian byte ordering and SHA uses big endian,
270 // reverse all the bytes when copying the final state to the output hash.
271 for (i = 0; i < 4; ++i)
272 {
273 hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
274 hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
275 hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
276 hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
277 hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
278 hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
279 hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
280 hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
281 }
282}
283
284#endif