"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/crypto.c" between
dnsmasq-2.80.tar.gz and dnsmasq-2.81.tar.xz

About: Dnsmasq is a lightweight caching DNS forwarder and DHCP server.

crypto.c  (dnsmasq-2.80):crypto.c  (dnsmasq-2.81.tar.xz)
/* dnsmasq is Copyright (c) 2000-2018 Simon Kelley /* dnsmasq is Copyright (c) 2000-2020 Simon Kelley
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; version 2 dated June, 1991, or the Free Software Foundation; version 2 dated June, 1991, or
(at your option) version 3 dated 29 June, 2007. (at your option) version 3 dated 29 June, 2007.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details. GNU General Public License for more details.
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>. along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
#include "dnsmasq.h" #include "dnsmasq.h"
#ifdef HAVE_DNSSEC #ifdef HAVE_DNSSEC
#include <nettle/rsa.h> #include <nettle/rsa.h>
#include <nettle/dsa.h>
#include <nettle/ecdsa.h> #include <nettle/ecdsa.h>
#include <nettle/ecc-curve.h> #include <nettle/ecc-curve.h>
#include <nettle/eddsa.h> #include <nettle/eddsa.h>
#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
# include <nettle/gostdsa.h>
#endif
#include <nettle/nettle-meta.h> #include <nettle/nettle-meta.h>
#include <nettle/bignum.h> #include <nettle/bignum.h>
/* Implement a "hash-function" to the nettle API, which simply returns /* Implement a "hash-function" to the nettle API, which simply returns
the input data, concatenated into a single, statically maintained, buffer. the input data, concatenated into a single, statically maintained, buffer.
Used for the EdDSA sigs, which operate on the whole message, rather Used for the EdDSA sigs, which operate on the whole message, rather
than a digest. */ than a digest. */
struct null_hash_digest struct null_hash_digest
skipping to change at line 209 skipping to change at line 211
return 0; return 0;
key->size = key_len - exp_len; key->size = key_len - exp_len;
mpz_import(key->e, exp_len, 1, 1, 0, 0, p); mpz_import(key->e, exp_len, 1, 1, 0, 0, p);
mpz_import(key->n, key->size, 1, 1, 0, 0, p + exp_len); mpz_import(key->n, key->size, 1, 1, 0, 0, p + exp_len);
mpz_import(sig_mpz, sig_len, 1, 1, 0, 0, sig); mpz_import(sig_mpz, sig_len, 1, 1, 0, 0, sig);
switch (algo) switch (algo)
{ {
case 1:
return nettle_rsa_md5_verify_digest(key, digest, sig_mpz);
case 5: case 7: case 5: case 7:
return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz); return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz);
case 8: case 8:
return nettle_rsa_sha256_verify_digest(key, digest, sig_mpz); return nettle_rsa_sha256_verify_digest(key, digest, sig_mpz);
case 10: case 10:
return nettle_rsa_sha512_verify_digest(key, digest, sig_mpz); return nettle_rsa_sha512_verify_digest(key, digest, sig_mpz);
} }
return 0; return 0;
} }
static int dnsmasq_dsa_verify(struct blockdata *key_data, unsigned int key_len,
unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo)
{
unsigned char *p;
unsigned int t;
static mpz_t y;
static struct dsa_params *params = NULL;
static struct dsa_signature *sig_struct;
(void)digest_len;
if (params == NULL)
{
if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
!(params = whine_malloc(sizeof(struct dsa_params))))
return 0;
mpz_init(y);
nettle_dsa_params_init(params);
nettle_dsa_signature_init(sig_struct);
}
if ((sig_len < 41) || !(p = blockdata_retrieve(key_data, key_len, NULL)))
return 0;
t = *p++;
if (key_len < (213 + (t * 24)))
return 0;
mpz_import(params->q, 20, 1, 1, 0, 0, p); p += 20;
mpz_import(params->p, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
mpz_import(params->g, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
mpz_import(y, 64 + (t*8), 1, 1, 0, 0, p); p += 64 + (t*8);
mpz_import(sig_struct->r, 20, 1, 1, 0, 0, sig+1);
mpz_import(sig_struct->s, 20, 1, 1, 0, 0, sig+21);
(void)algo;
return nettle_dsa_verify(params, y, digest_len, digest, sig_struct);
}
static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len , static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len ,
unsigned char *sig, size_t sig_len, unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int alg o) unsigned char *digest, size_t digest_len, int alg o)
{ {
unsigned char *p; unsigned char *p;
unsigned int t; unsigned int t;
struct ecc_point *key; struct ecc_point *key;
static struct ecc_point *key_256 = NULL, *key_384 = NULL; static struct ecc_point *key_256 = NULL, *key_384 = NULL;
static mpz_t x, y; static mpz_t x, y;
static struct dsa_signature *sig_struct; static struct dsa_signature *sig_struct;
#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR < 4
#define nettle_get_secp_256r1() (&nettle_secp_256r1)
#define nettle_get_secp_384r1() (&nettle_secp_384r1)
#endif
if (!sig_struct) if (!sig_struct)
{ {
if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature)))) if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))))
return 0; return 0;
nettle_dsa_signature_init(sig_struct); nettle_dsa_signature_init(sig_struct);
mpz_init(x); mpz_init(x);
mpz_init(y); mpz_init(y);
} }
switch (algo) switch (algo)
{ {
case 13: case 13:
if (!key_256) if (!key_256)
{ {
if (!(key_256 = whine_malloc(sizeof(struct ecc_point)))) if (!(key_256 = whine_malloc(sizeof(struct ecc_point))))
return 0; return 0;
nettle_ecc_point_init(key_256, &nettle_secp_256r1); nettle_ecc_point_init(key_256, nettle_get_secp_256r1());
} }
key = key_256; key = key_256;
t = 32; t = 32;
break; break;
case 14: case 14:
if (!key_384) if (!key_384)
{ {
if (!(key_384 = whine_malloc(sizeof(struct ecc_point)))) if (!(key_384 = whine_malloc(sizeof(struct ecc_point))))
return 0; return 0;
nettle_ecc_point_init(key_384, &nettle_secp_384r1); nettle_ecc_point_init(key_384, nettle_get_secp_384r1());
} }
key = key_384; key = key_384;
t = 48; t = 48;
break; break;
default: default:
return 0; return 0;
} }
skipping to change at line 336 skipping to change at line 296
if (!ecc_point_set(key, x, y)) if (!ecc_point_set(key, x, y))
return 0; return 0;
mpz_import(sig_struct->r, t, 1, 1, 0, 0, sig); mpz_import(sig_struct->r, t, 1, 1, 0, 0, sig);
mpz_import(sig_struct->s, t, 1, 1, 0, 0, sig + t); mpz_import(sig_struct->s, t, 1, 1, 0, 0, sig + t);
return nettle_ecdsa_verify(key, digest_len, digest, sig_struct); return nettle_ecdsa_verify(key, digest_len, digest, sig_struct);
} }
#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
static int dnsmasq_gostdsa_verify(struct blockdata *key_data, unsigned int key_l
en,
unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int a
lgo)
{
unsigned char *p;
static struct ecc_point *gost_key = NULL;
static mpz_t x, y;
static struct dsa_signature *sig_struct;
if (algo != 12 ||
sig_len != 64 || key_len != 64 ||
!(p = blockdata_retrieve(key_data, key_len, NULL)))
return 0;
if (!sig_struct)
{
if (!(sig_struct = whine_malloc(sizeof(struct dsa_signature))) ||
!(gost_key = whine_malloc(sizeof(struct ecc_point))))
return 0;
nettle_dsa_signature_init(sig_struct);
nettle_ecc_point_init(gost_key, nettle_get_gost_gc256b());
mpz_init(x);
mpz_init(y);
}
mpz_import(x, 32 , 1, 1, 0, 0, p);
mpz_import(y, 32 , 1, 1, 0, 0, p + 32);
if (!ecc_point_set(gost_key, x, y))
return 0;
mpz_import(sig_struct->r, 32, 1, 1, 0, 0, sig);
mpz_import(sig_struct->s, 32, 1, 1, 0, 0, sig + 32);
return nettle_gostdsa_verify(gost_key, digest_len, digest, sig_struct);
}
#endif
static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len , static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len ,
unsigned char *sig, size_t sig_len, unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int alg o) unsigned char *digest, size_t digest_len, int alg o)
{ {
unsigned char *p; unsigned char *p;
if (key_len != ED25519_KEY_SIZE || if (digest_len != sizeof(struct null_hash_digest) ||
sig_len != ED25519_SIGNATURE_SIZE ||
digest_len != sizeof(struct null_hash_digest) ||
!(p = blockdata_retrieve(key_data, key_len, NULL))) !(p = blockdata_retrieve(key_data, key_len, NULL)))
return 0; return 0;
/* The "digest" returned by the null_hash function is simply a struct null_has h_digest /* The "digest" returned by the null_hash function is simply a struct null_has h_digest
which has a pointer to the actual data and a length, because the buffer which has a pointer to the actual data and a length, because the buffer
may need to be extended during "hashing". */ may need to be extended during "hashing". */
switch (algo) switch (algo)
{ {
case 15: case 15:
if (key_len != ED25519_KEY_SIZE ||
sig_len != ED25519_SIGNATURE_SIZE)
return 0;
return ed25519_sha512_verify(p, return ed25519_sha512_verify(p,
((struct null_hash_digest *)digest)->len, ((struct null_hash_digest *)digest)->len,
((struct null_hash_digest *)digest)->buff, ((struct null_hash_digest *)digest)->buff,
sig); sig);
#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
case 16: case 16:
/* Ed448 when available */ if (key_len != ED448_KEY_SIZE ||
return 0; sig_len != ED448_SIGNATURE_SIZE)
return 0;
return ed448_shake256_verify(p,
((struct null_hash_digest *)digest)->len,
((struct null_hash_digest *)digest)->buff,
sig);
#endif
} }
return 0; return 0;
} }
static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key _len, unsigned char *sig, size_t sig_len, static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key _len, unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo) unsigned char *digest, size_t digest_len, int algo)
{ {
/* Enure at runtime that we have support for this digest */ /* Ensure at runtime that we have support for this digest */
if (!hash_find(algo_digest_name(algo))) if (!hash_find(algo_digest_name(algo)))
return NULL; return NULL;
/* This switch defines which sig algorithms we support, can't introspect Nettl e for that. */ /* This switch defines which sig algorithms we support, can't introspect Nettl e for that. */
switch (algo) switch (algo)
{ {
case 1: case 5: case 7: case 8: case 10: case 5: case 7: case 8: case 10:
return dnsmasq_rsa_verify; return dnsmasq_rsa_verify;
case 3: case 6: #if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
return dnsmasq_dsa_verify; case 12:
return dnsmasq_gostdsa_verify;
#endif
case 13: case 14: case 13: case 14:
return dnsmasq_ecdsa_verify; return dnsmasq_ecdsa_verify;
case 15: case 16: case 15: case 16:
return dnsmasq_eddsa_verify; return dnsmasq_eddsa_verify;
} }
return NULL; return NULL;
} }
skipping to change at line 434 skipping to change at line 449
} }
} }
/* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */ /* http://www.iana.org/assignments/dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml */
char *algo_digest_name(int algo) char *algo_digest_name(int algo)
{ {
switch (algo) switch (algo)
{ {
case 1: return NULL; /* RSA/MD5 - Must Not Implement. RFC 6944 par a 2.3. */ case 1: return NULL; /* RSA/MD5 - Must Not Implement. RFC 6944 par a 2.3. */
case 2: return NULL; /* Diffie-Hellman */ case 2: return NULL; /* Diffie-Hellman */
case 3: return "sha1"; /* DSA/SHA1 */ case 3: return NULL; ; /* DSA/SHA1 - Must Not Implement. RFC 8624 sec tion 3.1 */
case 5: return "sha1"; /* RSA/SHA1 */ case 5: return "sha1"; /* RSA/SHA1 */
case 6: return "sha1"; /* DSA-NSEC3-SHA1 */ case 6: return NULL; /* DSA-NSEC3-SHA1 - Must Not Implement. RFC 86 24 section 3.1 */
case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */ case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */
case 8: return "sha256"; /* RSA/SHA-256 */ case 8: return "sha256"; /* RSA/SHA-256 */
case 10: return "sha512"; /* RSA/SHA-512 */ case 10: return "sha512"; /* RSA/SHA-512 */
case 12: return NULL; /* ECC-GOST */ case 12: return "gosthash94"; /* ECC-GOST */
case 13: return "sha256"; /* ECDSAP256SHA256 */ case 13: return "sha256"; /* ECDSAP256SHA256 */
case 14: return "sha384"; /* ECDSAP384SHA384 */ case 14: return "sha384"; /* ECDSAP384SHA384 */
case 15: return "null_hash"; /* ED25519 */ case 15: return "null_hash"; /* ED25519 */
case 16: return NULL; /* ED448 */ case 16: return "null_hash"; /* ED448 */
default: return NULL; default: return NULL;
} }
} }
/* http://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-paramete rs.xhtml */ /* http://www.iana.org/assignments/dnssec-nsec3-parameters/dnssec-nsec3-paramete rs.xhtml */
char *nsec3_digest_name(int digest) char *nsec3_digest_name(int digest)
{ {
switch (digest) switch (digest)
{ {
case 1: return "sha1"; case 1: return "sha1";
 End of changes. 20 change blocks. 
64 lines changed or deleted 80 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)