diff signkey.c @ 1659:d32bcb5c557d

Add Ed25519 support (#91) * Add support for Ed25519 as a public key type Ed25519 is a elliptic curve signature scheme that offers better security than ECDSA and DSA and good performance. It may be used for both user and host keys. OpenSSH key import and fuzzer are not supported yet. Initially inspired by Peter Szabo. * Add curve25519 and ed25519 fuzzers * Add import and export of Ed25519 keys
author Vladislav Grishenko <themiron@users.noreply.github.com>
date Wed, 11 Mar 2020 21:09:45 +0500
parents 2f64cb3d3007
children ba6fc7afe1c5
line wrap: on
line diff
--- a/signkey.c	Fri Oct 18 23:48:16 2019 +0800
+++ b/signkey.c	Wed Mar 11 21:09:45 2020 +0500
@@ -39,8 +39,11 @@
 #if DROPBEAR_ECDSA
 	"ecdsa-sha2-nistp256",
 	"ecdsa-sha2-nistp384",
-	"ecdsa-sha2-nistp521"
+	"ecdsa-sha2-nistp521",
 #endif /* DROPBEAR_ECDSA */
+#if DROPBEAR_ED25519
+	"ssh-ed25519",
+#endif /* DROPBEAR_ED25519 */
 };
 
 /* malloc a new sign_key and set the dss and rsa keys to NULL */
@@ -107,6 +110,10 @@
 void **
 signkey_key_ptr(sign_key *key, enum signkey_type type) {
 	switch (type) {
+#if DROPBEAR_ED25519
+		case DROPBEAR_SIGNKEY_ED25519:
+			return (void**)&key->ed25519key;
+#endif
 #if DROPBEAR_ECDSA
 #if DROPBEAR_ECC_256
 		case DROPBEAR_SIGNKEY_ECDSA_NISTP256:
@@ -200,6 +207,17 @@
 		}
 	}
 #endif
+#if DROPBEAR_ED25519
+	if (keytype == DROPBEAR_SIGNKEY_ED25519) {
+		ed25519_key_free(key->ed25519key);
+		key->ed25519key = m_malloc(sizeof(*key->ed25519key));
+		ret = buf_get_ed25519_pub_key(buf, key->ed25519key);
+		if (ret == DROPBEAR_FAILURE) {
+			m_free(key->ed25519key);
+			key->ed25519key = NULL;
+		}
+	}
+#endif
 
 	TRACE2(("leave buf_get_pub_key"))
 
@@ -270,6 +288,17 @@
 		}
 	}
 #endif
+#if DROPBEAR_ED25519
+	if (keytype == DROPBEAR_SIGNKEY_ED25519) {
+		ed25519_key_free(key->ed25519key);
+		key->ed25519key = m_malloc(sizeof(*key->ed25519key));
+		ret = buf_get_ed25519_priv_key(buf, key->ed25519key);
+		if (ret == DROPBEAR_FAILURE) {
+			m_free(key->ed25519key);
+			key->ed25519key = NULL;
+		}
+	}
+#endif
 
 	TRACE2(("leave buf_get_priv_key"))
 
@@ -303,6 +332,11 @@
 		}
 	}
 #endif
+#if DROPBEAR_ED25519
+	if (type == DROPBEAR_SIGNKEY_ED25519) {
+		buf_put_ed25519_pub_key(pubkeys, key->ed25519key);
+	}
+#endif
 	if (pubkeys->len == 0) {
 		dropbear_exit("Bad key types in buf_put_pub_key");
 	}
@@ -342,6 +376,13 @@
 		}
 	}
 #endif
+#if DROPBEAR_ED25519
+	if (type == DROPBEAR_SIGNKEY_ED25519) {
+		buf_put_ed25519_priv_key(buf, key->ed25519key);
+		TRACE(("leave buf_put_priv_key: ed25519 done"))
+		return;
+	}
+#endif
 	dropbear_exit("Bad key types in put pub key");
 }
 
@@ -380,6 +421,10 @@
 	}
 #endif
 #endif
+#if DROPBEAR_ED25519
+	ed25519_key_free(key->ed25519key);
+	key->ed25519key = NULL;
+#endif
 
 	m_free(key->filename);
 
@@ -504,6 +549,11 @@
 		}
 	}
 #endif
+#if DROPBEAR_ED25519
+	if (type == DROPBEAR_SIGNKEY_ED25519) {
+		buf_put_ed25519_sign(sigblob, key->ed25519key, data_buf);
+	}
+#endif
 	if (sigblob->len == 0) {
 		dropbear_exit("Non-matching signing type");
 	}
@@ -555,6 +605,14 @@
 		}
 	}
 #endif
+#if DROPBEAR_ED25519
+	if (type == DROPBEAR_SIGNKEY_ED25519) {
+		if (key->ed25519key == NULL) {
+			dropbear_exit("No Ed25519 key to verify signature");
+		}
+		return buf_ed25519_verify(buf, key->ed25519key, data_buf);
+	}
+#endif
 
 	dropbear_exit("Non-matching signing type");
 	return DROPBEAR_FAILURE;