summaryrefslogtreecommitdiff
path: root/src/crypto.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/crypto.c')
-rw-r--r--src/crypto.c143
1 files changed, 79 insertions, 64 deletions
diff --git a/src/crypto.c b/src/crypto.c
index ebb871e..ca63111 100644
--- a/src/crypto.c
+++ b/src/crypto.c
@@ -1,4 +1,4 @@
-/* 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
it under the terms of the GNU General Public License as published by
@@ -19,10 +19,12 @@
#ifdef HAVE_DNSSEC
#include <nettle/rsa.h>
-#include <nettle/dsa.h>
#include <nettle/ecdsa.h>
#include <nettle/ecc-curve.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/bignum.h>
@@ -207,8 +209,6 @@ static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len,
switch (algo)
{
- case 1:
- return nettle_rsa_md5_verify_digest(key, digest, sig_mpz);
case 5: case 7:
return nettle_rsa_sha1_verify_digest(key, digest, sig_mpz);
case 8:
@@ -220,50 +220,6 @@ static int dnsmasq_rsa_verify(struct blockdata *key_data, unsigned int key_len,
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,
unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo)
@@ -275,6 +231,10 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
static struct ecc_point *key_256 = NULL, *key_384 = NULL;
static mpz_t x, y;
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)
{
@@ -294,7 +254,7 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
if (!(key_256 = whine_malloc(sizeof(struct ecc_point))))
return 0;
- nettle_ecc_point_init(key_256, &nettle_secp_256r1);
+ nettle_ecc_point_init(key_256, nettle_get_secp_256r1());
}
key = key_256;
@@ -307,7 +267,7 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
if (!(key_384 = whine_malloc(sizeof(struct ecc_point))))
return 0;
- nettle_ecc_point_init(key_384, &nettle_secp_384r1);
+ nettle_ecc_point_init(key_384, nettle_get_secp_384r1());
}
key = key_384;
@@ -334,15 +294,54 @@ static int dnsmasq_ecdsa_verify(struct blockdata *key_data, unsigned int key_len
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_len,
+ unsigned char *sig, size_t sig_len,
+ unsigned char *digest, size_t digest_len, int algo)
+{
+ 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,
unsigned char *sig, size_t sig_len,
unsigned char *digest, size_t digest_len, int algo)
{
unsigned char *p;
- if (key_len != ED25519_KEY_SIZE ||
- sig_len != ED25519_SIGNATURE_SIZE ||
- digest_len != sizeof(struct null_hash_digest) ||
+ if (digest_len != sizeof(struct null_hash_digest) ||
!(p = blockdata_retrieve(key_data, key_len, NULL)))
return 0;
@@ -353,13 +352,27 @@ static int dnsmasq_eddsa_verify(struct blockdata *key_data, unsigned int key_len
switch (algo)
{
case 15:
+ if (key_len != ED25519_KEY_SIZE ||
+ sig_len != ED25519_SIGNATURE_SIZE)
+ return 0;
+
return ed25519_sha512_verify(p,
((struct null_hash_digest *)digest)->len,
((struct null_hash_digest *)digest)->buff,
sig);
+
+#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
case 16:
- /* Ed448 when available */
- return 0;
+ if (key_len != ED448_KEY_SIZE ||
+ 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;
@@ -369,19 +382,21 @@ static int (*verify_func(int algo))(struct blockdata *key_data, unsigned int key
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)))
return NULL;
/* This switch defines which sig algorithms we support, can't introspect Nettle for that. */
switch (algo)
{
- case 1: case 5: case 7: case 8: case 10:
+ case 5: case 7: case 8: case 10:
return dnsmasq_rsa_verify;
+
+#if NETTLE_VERSION_MAJOR == 3 && NETTLE_VERSION_MINOR >= 6
+ case 12:
+ return dnsmasq_gostdsa_verify;
+#endif
- case 3: case 6:
- return dnsmasq_dsa_verify;
-
case 13: case 14:
return dnsmasq_ecdsa_verify;
@@ -432,17 +447,17 @@ char *algo_digest_name(int algo)
{
case 1: return NULL; /* RSA/MD5 - Must Not Implement. RFC 6944 para 2.3. */
case 2: return NULL; /* Diffie-Hellman */
- case 3: return "sha1"; /* DSA/SHA1 */
+ case 3: return NULL; ; /* DSA/SHA1 - Must Not Implement. RFC 8624 section 3.1 */
case 5: return "sha1"; /* RSA/SHA1 */
- case 6: return "sha1"; /* DSA-NSEC3-SHA1 */
+ case 6: return NULL; /* DSA-NSEC3-SHA1 - Must Not Implement. RFC 8624 section 3.1 */
case 7: return "sha1"; /* RSASHA1-NSEC3-SHA1 */
case 8: return "sha256"; /* RSA/SHA-256 */
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 14: return "sha384"; /* ECDSAP384SHA384 */
case 15: return "null_hash"; /* ED25519 */
- case 16: return NULL; /* ED448 */
+ case 16: return "null_hash"; /* ED448 */
default: return NULL;
}
}