[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