blob: fad32d7ee555d751e844d3d7a3aabe00ff8136e2 [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
Petr Menšík2024f972020-11-25 17:18:55 +010031#if defined(HAVE_DNSSEC) || defined(HAVE_NETTLEHASH)
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{
39 if (!(hash = hash_find("sha256")) || !hash_init(hash, &ctx, &digest))
40 die(_("Failed to create SHA-256 hash object"), NULL, EC_MISC);
41}
42
Simon Kelley2d765862020-11-12 22:06:07 +000043unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name)
44{
45 int q;
46 unsigned char *p = (unsigned char *)(header+1);
Simon Kelley2d765862020-11-12 22:06:07 +000047
Simon Kelleye75069f2021-01-22 22:50:25 +000048 hash->init(ctx);
49
Simon Kelley2d765862020-11-12 22:06:07 +000050 for (q = ntohs(header->qdcount); q != 0; q--)
51 {
52 char *cp, c;
53
54 if (!extract_name(header, plen, &p, name, 1, 4))
55 break; /* bad packet */
56
57 for (cp = name; (c = *cp); cp++)
58 if (c >= 'A' && c <= 'Z')
59 *cp += 'a' - 'A';
60
61 hash->update(ctx, cp - name, (unsigned char *)name);
62 /* CRC the class and type as well */
63 hash->update(ctx, 4, p);
64
65 p += 4;
66 if (!CHECK_LEN(header, p, plen, 0))
67 break; /* bad packet */
68 }
69
70 hash->digest(ctx, hash->digest_size, digest);
71 return digest;
72}
73
74#else /* HAVE_DNSSEC */
75
76#define SHA256_BLOCK_SIZE 32 // SHA256 outputs a 32 byte digest
77typedef unsigned char BYTE; // 8-bit byte
78typedef unsigned int WORD; // 32-bit word, change to "long" for 16-bit machines
79
80typedef struct {
81 BYTE data[64];
82 WORD datalen;
83 unsigned long long bitlen;
84 WORD state[8];
85} SHA256_CTX;
86
87static void sha256_init(SHA256_CTX *ctx);
88static void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len);
89static void sha256_final(SHA256_CTX *ctx, BYTE hash[]);
90
Simon Kelleye75069f2021-01-22 22:50:25 +000091void hash_questions_init(void)
92{
93}
Simon Kelley2d765862020-11-12 22:06:07 +000094
95unsigned char *hash_questions(struct dns_header *header, size_t plen, char *name)
96{
97 int q;
98 unsigned char *p = (unsigned char *)(header+1);
99 SHA256_CTX ctx;
100 static BYTE digest[SHA256_BLOCK_SIZE];
101
102 sha256_init(&ctx);
103
104 for (q = ntohs(header->qdcount); q != 0; q--)
105 {
106 char *cp, c;
107
108 if (!extract_name(header, plen, &p, name, 1, 4))
109 break; /* bad packet */
110
111 for (cp = name; (c = *cp); cp++)
112 if (c >= 'A' && c <= 'Z')
113 *cp += 'a' - 'A';
114
115 sha256_update(&ctx, (BYTE *)name, cp - name);
116 /* CRC the class and type as well */
117 sha256_update(&ctx, (BYTE *)p, 4);
118
119 p += 4;
120 if (!CHECK_LEN(header, p, plen, 0))
121 break; /* bad packet */
122 }
123
124 sha256_final(&ctx, digest);
125 return (unsigned char *)digest;
126}
127
128/* Code from here onwards comes from https://github.com/B-Con/crypto-algorithms
129 and was written by Brad Conte (brad@bradconte.com), to whom all credit is given.
130
131 This code is in the public domain, and the copyright notice at the head of this
132 file does not apply to it.
133*/
134
135
136/****************************** MACROS ******************************/
137#define ROTLEFT(a,b) (((a) << (b)) | ((a) >> (32-(b))))
138#define ROTRIGHT(a,b) (((a) >> (b)) | ((a) << (32-(b))))
139
140#define CH(x,y,z) (((x) & (y)) ^ (~(x) & (z)))
141#define MAJ(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
142#define EP0(x) (ROTRIGHT(x,2) ^ ROTRIGHT(x,13) ^ ROTRIGHT(x,22))
143#define EP1(x) (ROTRIGHT(x,6) ^ ROTRIGHT(x,11) ^ ROTRIGHT(x,25))
144#define SIG0(x) (ROTRIGHT(x,7) ^ ROTRIGHT(x,18) ^ ((x) >> 3))
145#define SIG1(x) (ROTRIGHT(x,17) ^ ROTRIGHT(x,19) ^ ((x) >> 10))
146
147/**************************** VARIABLES *****************************/
148static const WORD k[64] = {
149 0x428a2f98,0x71374491,0xb5c0fbcf,0xe9b5dba5,0x3956c25b,0x59f111f1,0x923f82a4,0xab1c5ed5,
150 0xd807aa98,0x12835b01,0x243185be,0x550c7dc3,0x72be5d74,0x80deb1fe,0x9bdc06a7,0xc19bf174,
151 0xe49b69c1,0xefbe4786,0x0fc19dc6,0x240ca1cc,0x2de92c6f,0x4a7484aa,0x5cb0a9dc,0x76f988da,
152 0x983e5152,0xa831c66d,0xb00327c8,0xbf597fc7,0xc6e00bf3,0xd5a79147,0x06ca6351,0x14292967,
153 0x27b70a85,0x2e1b2138,0x4d2c6dfc,0x53380d13,0x650a7354,0x766a0abb,0x81c2c92e,0x92722c85,
154 0xa2bfe8a1,0xa81a664b,0xc24b8b70,0xc76c51a3,0xd192e819,0xd6990624,0xf40e3585,0x106aa070,
155 0x19a4c116,0x1e376c08,0x2748774c,0x34b0bcb5,0x391c0cb3,0x4ed8aa4a,0x5b9cca4f,0x682e6ff3,
156 0x748f82ee,0x78a5636f,0x84c87814,0x8cc70208,0x90befffa,0xa4506ceb,0xbef9a3f7,0xc67178f2
157};
158
159/*********************** FUNCTION DEFINITIONS ***********************/
160static void sha256_transform(SHA256_CTX *ctx, const BYTE data[])
161{
162 WORD a, b, c, d, e, f, g, h, i, j, t1, t2, m[64];
163
164 for (i = 0, j = 0; i < 16; ++i, j += 4)
165 m[i] = (data[j] << 24) | (data[j + 1] << 16) | (data[j + 2] << 8) | (data[j + 3]);
166 for ( ; i < 64; ++i)
167 m[i] = SIG1(m[i - 2]) + m[i - 7] + SIG0(m[i - 15]) + m[i - 16];
168
169 a = ctx->state[0];
170 b = ctx->state[1];
171 c = ctx->state[2];
172 d = ctx->state[3];
173 e = ctx->state[4];
174 f = ctx->state[5];
175 g = ctx->state[6];
176 h = ctx->state[7];
177
178 for (i = 0; i < 64; ++i)
179 {
180 t1 = h + EP1(e) + CH(e,f,g) + k[i] + m[i];
181 t2 = EP0(a) + MAJ(a,b,c);
182 h = g;
183 g = f;
184 f = e;
185 e = d + t1;
186 d = c;
187 c = b;
188 b = a;
189 a = t1 + t2;
190 }
191
192 ctx->state[0] += a;
193 ctx->state[1] += b;
194 ctx->state[2] += c;
195 ctx->state[3] += d;
196 ctx->state[4] += e;
197 ctx->state[5] += f;
198 ctx->state[6] += g;
199 ctx->state[7] += h;
200}
201
202static void sha256_init(SHA256_CTX *ctx)
203{
204 ctx->datalen = 0;
205 ctx->bitlen = 0;
206 ctx->state[0] = 0x6a09e667;
207 ctx->state[1] = 0xbb67ae85;
208 ctx->state[2] = 0x3c6ef372;
209 ctx->state[3] = 0xa54ff53a;
210 ctx->state[4] = 0x510e527f;
211 ctx->state[5] = 0x9b05688c;
212 ctx->state[6] = 0x1f83d9ab;
213 ctx->state[7] = 0x5be0cd19;
214}
215
216static void sha256_update(SHA256_CTX *ctx, const BYTE data[], size_t len)
217{
218 WORD i;
219
220 for (i = 0; i < len; ++i)
221 {
222 ctx->data[ctx->datalen] = data[i];
223 ctx->datalen++;
224 if (ctx->datalen == 64) {
225 sha256_transform(ctx, ctx->data);
226 ctx->bitlen += 512;
227 ctx->datalen = 0;
228 }
229 }
230}
231
232static void sha256_final(SHA256_CTX *ctx, BYTE hash[])
233{
234 WORD i;
235
236 i = ctx->datalen;
237
238 // Pad whatever data is left in the buffer.
239 if (ctx->datalen < 56)
240 {
241 ctx->data[i++] = 0x80;
242 while (i < 56)
243 ctx->data[i++] = 0x00;
244 }
245 else
246 {
247 ctx->data[i++] = 0x80;
248 while (i < 64)
249 ctx->data[i++] = 0x00;
250 sha256_transform(ctx, ctx->data);
251 memset(ctx->data, 0, 56);
252 }
253
254 // Append to the padding the total message's length in bits and transform.
255 ctx->bitlen += ctx->datalen * 8;
256 ctx->data[63] = ctx->bitlen;
257 ctx->data[62] = ctx->bitlen >> 8;
258 ctx->data[61] = ctx->bitlen >> 16;
259 ctx->data[60] = ctx->bitlen >> 24;
260 ctx->data[59] = ctx->bitlen >> 32;
261 ctx->data[58] = ctx->bitlen >> 40;
262 ctx->data[57] = ctx->bitlen >> 48;
263 ctx->data[56] = ctx->bitlen >> 56;
264 sha256_transform(ctx, ctx->data);
265
266 // Since this implementation uses little endian byte ordering and SHA uses big endian,
267 // reverse all the bytes when copying the final state to the output hash.
268 for (i = 0; i < 4; ++i)
269 {
270 hash[i] = (ctx->state[0] >> (24 - i * 8)) & 0x000000ff;
271 hash[i + 4] = (ctx->state[1] >> (24 - i * 8)) & 0x000000ff;
272 hash[i + 8] = (ctx->state[2] >> (24 - i * 8)) & 0x000000ff;
273 hash[i + 12] = (ctx->state[3] >> (24 - i * 8)) & 0x000000ff;
274 hash[i + 16] = (ctx->state[4] >> (24 - i * 8)) & 0x000000ff;
275 hash[i + 20] = (ctx->state[5] >> (24 - i * 8)) & 0x000000ff;
276 hash[i + 24] = (ctx->state[6] >> (24 - i * 8)) & 0x000000ff;
277 hash[i + 28] = (ctx->state[7] >> (24 - i * 8)) & 0x000000ff;
278 }
279}
280
281#endif