[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH 4/4] chachapoly: add chachapoly structures with compilation conditions (chacha20-poly1305@xxxxxxxxxxx support)
[Thread Prev] | [Thread Next]
- Subject: [PATCH 4/4] chachapoly: add chachapoly structures with compilation conditions (chacha20-poly1305@xxxxxxxxxxx support)
- From: Meng Hourk Tan <mtan@xxxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Mon, 18 Sep 2017 09:50:31 +0000
- To: "libssh@xxxxxxxxxx" <libssh@xxxxxxxxxx>
From 78b054eae890e36a556d1ed46df73b5f15f5df69 Mon Sep 17 00:00:00 2001
From: Meng Tan <mtan@xxxxxxxxxx>
Date: Mon, 18 Sep 2017 11:34:50 +0200
Subject: [PATCH 4/4] chachapoly: add chachapoly structures with compilation
conditions (chacha20-poly1305@xxxxxxxxxxx support)
Signed-off-by: Meng Tan <mtan@xxxxxxxxxx>
---
include/libssh/crypto.h | 7 +++++
include/libssh/wrapper.h | 4 +++
src/kex.c | 14 ++++++---
src/libcrypto.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++
src/libgcrypt.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++
src/packet_crypt.c | 13 +++++++++
6 files changed, 180 insertions(+), 4 deletions(-)
diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h
index 0cdf96b..0465f21 100644
--- a/include/libssh/crypto.h
+++ b/include/libssh/crypto.h
@@ -32,6 +32,10 @@
#endif
#include "libssh/wrapper.h"
+#ifdef WITH_CHACHAPOLY
+#include "libssh/chachapoly.h"
+#endif
+
#ifdef cbc_encrypt
#undef cbc_encrypt
#endif
@@ -144,6 +148,9 @@ struct ssh_cipher_struct {
EVP_CIPHER_CTX *ctx;
#endif
unsigned int authlen; /* length of mac for authenticated ciphers */
+#ifdef WITH_CHACHAPOLY
+ struct chachapoly_ctx *chachapoly;
+#endif
unsigned int keysize; /* bytes of key used. != keylen */
/* sets the new key for immediate use */
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h
index 09a9ee9..8569d5f 100644
--- a/include/libssh/wrapper.h
+++ b/include/libssh/wrapper.h
@@ -101,5 +101,9 @@ void ssh_reseed(void);
void ssh_cipher_clear(struct ssh_cipher_struct *cipher);
struct ssh_hmac_struct *ssh_get_hmactab(void);
const char *ssh_hmac_type_to_string(enum ssh_hmac_e hmac_type);
+#ifdef WITH_CHACHAPOLY
+uint32_t chachapoly_getlength(struct ssh_cipher_struct *cipher, const void* in,
+ unsigned long len, unsigned int seqnr);
+#endif
#endif /* WRAPPER_H_ */
diff --git a/src/kex.c b/src/kex.c
index 21523fa..694a6bb 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -65,6 +65,12 @@
# define DES_SUPPORTED "3des-cbc,des-cbc-ssh1"
#endif /* HAVE_LIBCRYPTO */
+#ifdef WITH_CHACHAPOLY
+#define CHACHAPOLY "chacha20-poly1305@xxxxxxxxxxx,"
+#else
+#define CHACHAPOLY ""
+#endif
+
#ifdef WITH_ZLIB
#define ZLIB "none,zlib,zlib@xxxxxxxxxxx"
#else
@@ -92,8 +98,8 @@
static const char *default_methods[] = {
KEY_EXCHANGE,
HOSTKEYS,
- AES BLOWFISH DES,
- AES BLOWFISH DES,
+ AES CHACHAPOLY BLOWFISH DES,
+ AES CHACHAPOLY BLOWFISH DES,
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"none",
@@ -107,8 +113,8 @@ static const char *default_methods[] = {
static const char *supported_methods[] = {
KEY_EXCHANGE,
HOSTKEYS,
- AES BLOWFISH DES_SUPPORTED,
- AES BLOWFISH DES_SUPPORTED,
+ AES CHACHAPOLY BLOWFISH DES_SUPPORTED,
+ AES CHACHAPOLY BLOWFISH DES_SUPPORTED,
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
ZLIB,
diff --git a/src/libcrypto.c b/src/libcrypto.c
index 0c5bf92..22fac06 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -60,6 +60,10 @@
#include "libssh/crypto.h"
+#ifdef WITH_CHACHAPOLY
+#include "libssh/chachapoly.h"
+#endif
+
struct ssh_mac_ctx_struct {
enum ssh_mac_e mac_type;
union {
@@ -718,6 +722,60 @@ static void des_cleanup(struct ssh_cipher_struct *cipher){
#endif /* HAS_DES */
+#ifdef WITH_CHACHAPOLY
+static int alloc_chachapoly(struct ssh_cipher_struct *cipher) {
+ cipher->chachapoly = malloc(sizeof(struct chachapoly_ctx));
+ if (cipher->chachapoly == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int chachapoly_set_key(struct ssh_cipher_struct *cipher, void *key,
+ void *IV) {
+ (void)IV;
+ if (cipher->chachapoly == NULL) {
+ if (alloc_chachapoly(cipher) < 0) {
+ return -1;
+ }
+ if (chachapoly_init(cipher->chachapoly,key,cipher->keysize / 8) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int chachapoly_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+ unsigned long len, unsigned int seqnr) {
+ int res;
+ res = chachapoly_crypt(cipher->chachapoly, seqnr, out, in, len - 4, 4,
+ cipher->authlen, 1);
+ return res;
+}
+
+static int chachapoly_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+ unsigned long len, unsigned int seqnr) {
+ int res;
+ res = chachapoly_crypt(cipher->chachapoly, seqnr, out, in, len - 4, 4,
+ cipher->authlen, 0);
+ return res;
+}
+
+static void chachapoly_cleanup(struct ssh_cipher_struct *cipher) {
+ if (cipher->chachapoly != NULL) {
+ BURN_BUFFER(cipher->chachapoly, sizeof(struct chachapoly_ctx));
+ SAFE_FREE(cipher->chachapoly);
+ }
+}
+uint32_t chachapoly_getlength(struct ssh_cipher_struct *cipher, const void* in,
+ unsigned long len, unsigned int seqnr) {
+ uint32_t plenp = 0;
+ chachapoly_get_length(cipher->chachapoly, &plenp, seqnr, in, len);
+ return plenp;
+}
+#endif /* WITH_CHACHAPOLY */
+
/*
* The table of supported ciphers
*/
@@ -890,6 +948,20 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.cleanup = des_cleanup
},
#endif /* HAS_DES */
+#ifdef WITH_CHACHAPOLY
+ {
+ .name = "chacha20-poly1305@xxxxxxxxxxx",
+ .blocksize = 8,
+ .ciphertype = SSH_CHACHAPOLY,
+ .authlen = 16,
+ .keysize = 512,
+ .set_encrypt_key = chachapoly_set_key,
+ .set_decrypt_key = chachapoly_set_key,
+ .encrypt = chachapoly_encrypt,
+ .decrypt = chachapoly_decrypt,
+ .cleanup = chachapoly_cleanup
+ },
+#endif
{
.name = NULL
}
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index 22eaa00..aa7cdb1 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -33,6 +33,10 @@
#ifdef HAVE_LIBGCRYPT
#include <gcrypt.h>
+#ifdef WITH_CHACHAPOLY
+#include "libssh/chachapoly.h"
+#endif
+
struct ssh_mac_ctx_struct {
enum ssh_mac_e mac_type;
gcry_md_hd_t ctx;
@@ -543,6 +547,60 @@ static int des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
return SSH_CRYPT_OK;
}
+#ifdef WITH_CHACHAPOLY
+static int alloc_chachapoly(struct ssh_cipher_struct *cipher) {
+ cipher->chachapoly = malloc(sizeof(struct chachapoly_ctx));
+ if (cipher->chachapoly == NULL) {
+ return -1;
+ }
+
+ return 0;
+}
+
+static int chachapoly_set_key(struct ssh_cipher_struct *cipher, void *key,
+ void *IV) {
+ (void)IV;
+ if (cipher->chachapoly == NULL) {
+ if (alloc_chachapoly(cipher) < 0) {
+ return -1;
+ }
+ if (chachapoly_init(cipher->chachapoly,key,cipher->keysize / 8) < 0) {
+ return -1;
+ }
+ }
+ return 0;
+}
+
+static int chachapoly_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+ unsigned long len, unsigned int seqnr) {
+ int res;
+ res = chachapoly_crypt(cipher->chachapoly, seqnr, out, in, len - 4, 4,
+ cipher->authlen, 1);
+ return res;
+}
+
+static int chachapoly_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+ unsigned long len, unsigned int seqnr) {
+ int res;
+ res = chachapoly_crypt(cipher->chachapoly, seqnr, out, in, len - 4, 4,
+ cipher->authlen, 0);
+ return res;
+}
+
+static void chachapoly_cleanup(struct ssh_cipher_struct *cipher) {
+ if (cipher->chachapoly != NULL) {
+ BURN_BUFFER(cipher->chachapoly, sizeof(struct chachapoly_ctx));
+ SAFE_FREE(cipher->chachapoly);
+ }
+}
+uint32_t chachapoly_getlength(struct ssh_cipher_struct *cipher, const void* in,
+ unsigned long len, unsigned int seqnr) {
+ uint32_t plenp = 0;
+ chachapoly_get_length(cipher->chachapoly, &plenp, seqnr, in, len);
+ return plenp;
+}
+#endif /* WITH_CHACHAPOLY */
+
/* the table of supported ciphers */
static struct ssh_cipher_struct ssh_ciphertab[] = {
{
@@ -665,6 +723,22 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.encrypt = des1_1_encrypt,
.decrypt = des1_1_decrypt
},
+#ifdef WITH_CHACHAPOLY
+ {
+ .name = "chacha20-poly1305@xxxxxxxxxxx",
+ .blocksize = 8,
+ .ciphertype = SSH_CHACHAPOLY,
+ .keylen = 64,
+ .key = NULL,
+ .authlen = 16,
+ .keysize = 512,
+ .set_encrypt_key = chachapoly_set_key,
+ .set_decrypt_key = chachapoly_set_key,
+ .encrypt = chachapoly_encrypt,
+ .decrypt = chachapoly_decrypt,
+ .cleanup = chachapoly_cleanup,
+ },
+#endif
{
.name = NULL,
.blocksize = 0,
diff --git a/src/packet_crypt.c b/src/packet_crypt.c
index 6265844..592d9af 100644
--- a/src/packet_crypt.c
+++ b/src/packet_crypt.c
@@ -48,6 +48,19 @@ uint32_t ssh_packet_decrypt_len(ssh_session session, char *crypted){
uint32_t decrypted;
if (session->current_crypto) {
+#ifdef WITH_CHACHAPOLY
+ if (session->current_crypto->in_cipher->ciphertype == SSH_CHACHAPOLY) {
+ if (session->current_crypto->in_cipher->set_decrypt_key(
+ session->current_crypto->in_cipher,
+ session->current_crypto->decryptkey,
+ session->current_crypto->decryptIV) < 0) {
+ return 0;
+ }
+ decrypted = chachapoly_getlength(session->current_crypto->in_cipher, crypted,
+ 4, session->recv_seq);
+ return decrypted;
+ }
+#endif
if (ssh_packet_decrypt(session, crypted,
session->current_crypto->in_cipher->blocksize) < 0) {
return 0;
--
2.1.4
Archive administrator: postmaster@lists.cynapses.org