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