blob: 4009569a1734f80df543aec44a0250eeaf2d3624 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001/* dnsmasq is Copyright (c) 2000-2021 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#include "dnsmasq.h"
18
19#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
20
21/* Minimal version of nettle */
22
23/* bignum.h includes version.h and works on
24 earlier releases of nettle which don't have version.h */
25#include <nettle/bignum.h>
26#if !defined(NETTLE_VERSION_MAJOR)
27# define NETTLE_VERSION_MAJOR 2
28# define NETTLE_VERSION_MINOR 0
29#endif
30#define MIN_VERSION(major, minor) ((NETTLE_VERSION_MAJOR == (major) && NETTLE_VERSION_MINOR >= (minor)) || \
31 (NETTLE_VERSION_MAJOR > (major)))
32
33#endif /* defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH) */
34
35#if defined(HAVE_DNSSEC)
36#include <nettle/rsa.h>
37#include <nettle/ecdsa.h>
38#include <nettle/ecc-curve.h>
39#if MIN_VERSION(3, 1)
40#include <nettle/eddsa.h>
41#endif
42#if MIN_VERSION(3, 6)
43# include <nettle/gostdsa.h>
44#endif
45
46#if MIN_VERSION(3, 1)
47/* Implement a "hash-function" to the nettle API, which simply returns
48 the input data, concatenated into a single, statically maintained, buffer.
49
50 Used for the EdDSA sigs, which operate on the whole message, rather
51 than a digest. */
52
53struct null_hash_digest
54{
55 uint8_t *buff;
56 size_t len;
57};
58
59struct null_hash_ctx
60{
61 size_t len;
62};
63
64static size_t null_hash_buff_sz = 0;
65static uint8_t *null_hash_buff = NULL;
66#define BUFF_INCR 128
67
68static void null_hash_init(void *ctx)
69{
70 ((struct null_hash_ctx *)ctx)->len = 0;
71}
72
73static void null_hash_update(void *ctxv, size_t length, const uint8_t *src)
74{
75 struct null_hash_ctx *ctx = ctxv;
76 size_t new_len = ctx->len + length;
77
78 if (new_len > null_hash_buff_sz)
79 {
80 uint8_t *new;
81
82 if (!(new = whine_malloc(new_len + BUFF_INCR)))
83 return;
84
85 if (null_hash_buff)
86 {
87 if (ctx->len != 0)
88 memcpy(new, null_hash_buff, ctx->len);
89 free(null_hash_buff);
90 }
91
92 null_hash_buff_sz = new_len + BUFF_INCR;
93 null_hash_buff = new;
94 }
95
96 memcpy(null_hash_buff + ctx->len, src, length);
97 ctx->len += length;
98}
99
100static void null_hash_digest(void *ctx, size_t length, uint8_t *dst)
101{
102 (void)length;
103
104 ((struct null_hash_digest *)dst)->buff = null_hash_buff;
105 ((struct null_hash_digest *)dst)->len = ((struct null_hash_ctx *)ctx)->len;
106}
107
108static struct nettle_hash null_hash = {
109 "null_hash",
110 sizeof(struct null_hash_ctx),
111 sizeof(struct null_hash_digest),
112 0,
113 (nettle_hash_init_func *) null_hash_init,
114 (nettle_hash_update_func *) null_hash_update,
115 (nettle_hash_digest_func *) null_hash_digest
116};
117
118#endif /* MIN_VERSION(3, 1) */
119
120/* expand ctx and digest memory allocations if necessary and init hash function */
121int hash_init(const struct nettle_hash *hash, void **ctxp, unsigned char **digestp)
122{
123 static void *ctx = NULL;
124 static unsigned char *digest = NULL;
125 static unsigned int ctx_sz = 0;
126 static unsigned int digest_sz = 0;
127
128 void *new;
129
130 if (ctx_sz < hash->context_size)
131 {
132 if (!(new = whine_malloc(hash->context_size)))
133 return 0;
134 if (ctx)
135 free(ctx);
136 ctx = new;
137 ctx_sz = hash->context_size;
138 }
139
140 if (digest_sz < hash->digest_size)
141 {
142 if (!(new = whine_malloc(hash->digest_size)))
143 return 0;
144 if (digest)
145 free(digest);
146 digest = new;
147 digest_sz = hash->digest_size;
148 }
149
150 *ctxp = ctx;
151 *digestp = digest;
152
153 hash->init(ctx);
154
155 return 1;
156}
157
158static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
159 unsigned char *digest, size_t digest_len, int algo)
160{
161 unsigned char *p;
162 size_t exp_len;
163
164 static struct rsa_public_key *key = NULL;
165 static mpz_t sig_mpz;
166
167 (void)digest_len;
168
169 if (key == NULL)
170 {
171 if (!(key = whine_malloc(sizeof(struct rsa_public_key))))
172 return 0;
173
174 nettle_rsa_public_key_init(key);
175 mpz_init(sig_mpz);
176 }
177
178 if ((key_len < 3) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
179 return 0;
180
181 key_len--;
182 if ((exp_len = *p++) == 0)
183 {
184 GETSHORT(exp_len, p);
185 key_len -= 2;
186 }
187
188 if (exp_len >= key_len)
189 return 0;
190
191 key->size = key_len - exp_len;
192 mpz_import(key->e, exp_len, 1, 1, 0, 0, p);
193 mpz_import(key->n, key->size, 1, 1, 0, 0, p + exp_len);
194
195 mpz_import(sig_mpz, sig_len, 1, 1, 0, 0, sig);
196
197 switch (algo)
198 {
199 case 5: case 7:
200 return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz);
201 case 8:
202 return nettle_rsa_sha256_verify_digest(key, digest, sig_mpz);
203 case 10:
204 return nettle_rsa_sha512_verify_digest(key, digest, sig_mpz);
205 }
206
207 return 0;
208}
209
210static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len,
211 unsigned char *sig, size_t sig_len,
212 unsigned char *digest, size_t digest_len, int algo)
213{
214 unsigned char *p;
215 unsigned int t;
216 struct ecc_point *key;
217
218 static struct ecc_point *key_256 = NULL, *key_384 = NULL;
219 static mpz_t x, y;
220 static struct dsa_signature *sig_struct;
221#if !MIN_VERSION(3, 4)
222#define nettle_get_secp_256r1() (&nettle_secp_256r1)
223#define nettle_get_secp_384r1() (&nettle_secp_384r1)
224#endif
225
226 if (!sig_struct)
227 {
228 if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))))
229 return 0;
230
231 nettle_dsa_signature_init(sig_struct);
232 mpz_init(x);
233 mpz_init(y);
234 }
235
236 switch (algo)
237 {
238 case 13:
239 if (!key_256)
240 {
241 if (!(key_256 = whine_malloc(sizeof(struct ecc_point))))
242 return 0;
243
244 nettle_ecc_point_init(key_256, nettle_get_secp_256r1());
245 }
246
247 key = key_256;
248 t = 32;
249 break;
250
251 case 14:
252 if (!key_384)
253 {
254 if (!(key_384 = whine_malloc(sizeof(struct ecc_point))))
255 return 0;
256
257 nettle_ecc_point_init(key_384, nettle_get_secp_384r1());
258 }
259
260 key = key_384;
261 t = 48;
262 break;
263
264 default:
265 return 0;
266 }
267
268 if (sig_len != 2*t || key_len != 2*t ||
269 !(p = blockdata_retrieve(key_data, key_len, NULL)))
270 return 0;
271
272 mpz_import(x, t , 1, 1, 0, 0, p);
273 mpz_import(y, t , 1, 1, 0, 0, p + t);
274
275 if (!ecc_point_set(key, x, y))
276 return 0;
277
278 mpz_import(sig_struct->r, t, 1, 1, 0, 0, sig);
279 mpz_import(sig_struct->s, t, 1, 1, 0, 0, sig + t);
280
281 return nettle_ecdsa_verify(key, digest_len, digest, sig_struct);
282}
283
284#if MIN_VERSION(3, 6)
285static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_len,
286 unsigned char *sig, size_t sig_len,
287 unsigned char *digest, size_t digest_len, int algo)
288{
289 unsigned char *p;
290
291 static struct ecc_point *gost_key = NULL;
292 static mpz_t x, y;
293 static struct dsa_signature *sig_struct;
294
295 if (algo != 12 ||
296 sig_len != 64 || key_len != 64 ||
297 !(p = blockdata_retrieve(key_data, key_len, NULL)))
298 return 0;
299
300 if (!sig_struct)
301 {
302 if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
303 !(gost_key = whine_malloc(sizeof(struct ecc_point))))
304 return 0;
305
306 nettle_dsa_signature_init(sig_struct);
307 nettle_ecc_point_init(gost_key, nettle_get_gost_gc256b());
308 mpz_init(x);
309 mpz_init(y);
310 }
311
312 mpz_import(x, 32 , 1, 1, 0, 0, p);
313 mpz_import(y, 32 , 1, 1, 0, 0, p + 32);
314
315 if (!ecc_point_set(gost_key, x, y))
316 return 0;
317
318 mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig);
319 mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig + 32);
320
321 return nettle_gostdsa_verify(gost_key, digest_len, digest, sig_struct);
322}
323#endif
324
325#if MIN_VERSION(3, 1)
326static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len,
327 unsigned char *sig, size_t sig_len,
328 unsigned char *digest, size_t digest_len, int algo)
329{
330 unsigned char *p;
331
332 if (digest_len != sizeof(struct null_hash_digest) ||
333 !(p = blockdata_retrieve(key_data, key_len, NULL)))
334 return 0;
335
336 /* The "digest" returned by the null_hash function is simply a struct null_hash_digest
337 which has a pointer to the actual data and a length, because the buffer
338 may need to be extended during "hashing". */
339
340 switch (algo)
341 {
342 case 15:
343 if (key_len != ED25519_KEY_SIZE ||
344 sig_len != ED25519_SIGNATURE_SIZE)
345 return 0;
346
347 return ed25519_sha512_verify(p,
348 ((struct null_hash_digest *)digest)->len,
349 ((struct null_hash_digest *)digest)->buff,
350 sig);
351
352#if MIN_VERSION(3, 6)
353 case 16:
354 if (key_len != ED448_KEY_SIZE ||
355 sig_len != ED448_SIGNATURE_SIZE)
356 return 0;
357
358 return ed448_shake256_verify(p,
359 ((struct null_hash_digest *)digest)->len,
360 ((struct null_hash_digest *)digest)->buff,
361 sig);
362#endif
363
364 }
365
366 return 0;
367}
368#endif
369
370static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
371 unsigned char *digest, size_t digest_len, int algo)
372{
373
374 /* Ensure at runtime that we have support for this digest */
375 if (!hash_find(algo_digest_name(algo)))
376 return NULL;
377
378 /* This switch defines which sig algorithms we support, can't introspect Nettle for that. */
379 switch (algo)
380 {
381 case 5: case 7: case 8: case 10:
382 return dnsmasq_rsa_verify;
383
384#if MIN_VERSION(3, 6)
385 case 12:
386 return dnsmasq_gostdsa_verify;
387#endif
388
389 case 13: case 14:
390 return dnsmasq_ecdsa_verify;
391
392#if MIN_VERSION(3, 1)
393 case 15: case 16:
394 return dnsmasq_eddsa_verify;
395#endif
396 }
397
398 return NULL;
399}
400
401int verify(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
402 unsigned char *digest, size_t digest_len, int algo)
403{
404
405 int (*func)(struct blockdata *key_data, unsigned int key_len, unsigned char *sig, size_t sig_len,
406 unsigned char *digest, size_t digest_len, int algo);
407
408 func = verify_func(algo);
409
410 if (!func)
411 return 0;
412
413 return (*func)(key_data, key_len, sig, sig_len, digest, digest_len, algo);
414}
415
416/* Note the ds_digest_name(), algo_digest_name() and nsec3_digest_name()
417 define which algo numbers we support. If algo_digest_name() returns
418 non-NULL for an algorithm number, we assume that algorithm is
419 supported by verify(). */
420
421/* http://www.iana.org/assignments/ds-rr-types/ds-rr-types.xhtml */
422char *ds_digest_name(int digest)
423{
424 switch (digest)
425 {
426 case 1: return "sha1";
427 case 2: return "sha256";
428 case 3: return "gosthash94";
429 case 4: return "sha384";
430 default: return NULL;
431 }
432}
433
434/* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
435char *algo_digest_name(int algo)
436{
437 switch (algo)
438 {
439 case 1: return NULL; /* RSA/MD5 - Must Not Implement. RFC 6944 para 2.3. */
440 case 2: return NULL; /* Diffie-Hellman */
441 case 3: return NULL; ; /* DSA/SHA1 - Must Not Implement. RFC 8624 section 3.1 */
442 case 5: return "sha1"; /* RSA/SHA1 */
443 case 6: return NULL; /* DSA-NSEC3-SHA1 - Must Not Implement. RFC 8624 section 3.1 */
444 case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */
445 case 8: return "sha256"; /* RSA/SHA-256 */
446 case 10: return "sha512"; /* RSA/SHA-512 */
447 case 12: return "gosthash94"; /* ECC-GOST */
448 case 13: return "sha256"; /* ECDSAP256SHA256 */
449 case 14: return "sha384"; /* ECDSAP384SHA384 */
450 case 15: return "null_hash"; /* ED25519 */
451 case 16: return "null_hash"; /* ED448 */
452 default: return NULL;
453 }
454}
455
456/* http://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-parameters.xhtml */
457char *nsec3_digest_name(int digest)
458{
459 switch (digest)
460 {
461 case 1: return "sha1";
462 default: return NULL;
463 }
464}
465
466#endif /* defined(HAVE_DNSSEC) */
467
468#if defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH)
469/* Find pointer to correct hash function in nettle library */
470const struct nettle_hash *hash_find(char *name)
471{
472 if (!name)
473 return NULL;
474
475#if MIN_VERSION(3,1) && defined(HAVE_DNSSEC)
476 /* We provide a "null" hash which returns the input data as digest. */
477 if (strcmp(null_hash.name, name) == 0)
478 return &null_hash;
479#endif
480
481 /* libnettle >= 3.4 provides nettle_lookup_hash() which avoids nasty ABI
482 incompatibilities if sizeof(nettle_hashes) changes between library
483 versions. */
484#if MIN_VERSION(3, 4)
485 return nettle_lookup_hash(name);
486#else
487 {
488 int i;
489
490 for (i = 0; nettle_hashes[i]; i++)
491 if (strcmp(nettle_hashes[i]->name, name) == 0)
492 return nettle_hashes[i];
493 }
494
495 return NULL;
496#endif
497}
498
499#endif /* defined(HAVE_DNSSEC) || defined(HAVE_CRYPTOHASH) */