[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Missing signed-off for pkg chacha20 patches
[Thread Prev] | [Thread Next]
- Subject: Re: Missing signed-off for pkg chacha20 patches
- From: Jon Simons <jon@xxxxxxxxxxxxx>
- Reply-to: libssh@xxxxxxxxxx
- Date: Fri, 8 Jun 2018 16:58:57 -0700
- To: Andreas Schneider <asn@xxxxxxxxxxxxxx>, libssh@xxxxxxxxxx
On 6/8/18 7:09 AM, Andreas Schneider wrote: > I'm currently working on chacha20 to merge Aris his work. There are two pkd > patches from you which don't have a Signed-off-by tag from you. > > Could you please give me the permission to add it or send the attached patch > back with them? > > Also, could you test this patchset? Excited to see the chacha20 work headed to master. I gave the patchset some review and testing this afternoon and I've attached a respin of the patchset that includes: * fixes for current master pkd: https://www.libssh.org/archive/libssh/2018-05/0000009.html * the older chacha20 patches now with my Signed-off * a couple of minor adjustments plus fix for the mbedTLS build These should apply cleanly on to 0940b0f29b4fef86e56dffdd13d978f9692b78fc. I tested this series with these combinations of pkd: * Debian Jessie with OpenSSL 1.0.1, libgcrypt20 * Debian Stretch with OpenSSL 1.1.0, libgcrypt20, mbedTLS Please let me know if I can be of any further help or if you'd like to see any changes to the adjustments I made. I can also send out the patches in another format if that would be helpful. Thanks, -Jon
From aa4ade54f781eec6362a6d57f66243d27c220dd4 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Thu, 24 May 2018 19:49:46 -0700
Subject: [PATCH 01/27] pkd: fix missing config.h #include
Ensure to include config.h so that the `HAVE_DSA` value is properly set
when building the pkd tests.
Introduced with 778652460f7cceb3e760964a890ffd99ec8230e7,
Testing done: with this change, the `pkd_hello` test is passing on an
OpenSSL 1.1.0 build for me. Previously it would fail pubkey exchange
early on for DSA- and ECDSA-type host keys.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
tests/pkd/pkd_daemon.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/pkd/pkd_daemon.h b/tests/pkd/pkd_daemon.h
index 3107ed1e..7bdf894d 100644
--- a/tests/pkd/pkd_daemon.h
+++ b/tests/pkd/pkd_daemon.h
@@ -8,6 +8,8 @@
#ifndef __PKD_DAEMON_H__
#define __PKD_DAEMON_H__
+#include "config.h"
+
enum pkd_hostkey_type_e {
PKD_RSA,
#ifdef HAVE_DSA
--
2.14.1
From 50bf63f4286ae620b3f4a04208b390d143526875 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 25 May 2018 03:00:33 -0700
Subject: [PATCH 02/27] ecdh: fix SSH_MSG_KEXDH_REPLY for libcrypto
Ensure to provide the `ssh_string` pubkey blob to the buffer packing
routine when computing the SSH_MSG_KEXDH_REPLY message, rather than
the new `ssh_key` type.
Introduced with 16217454d576511f37f39c3169963629f9d5082f.
Testing done: with this change, `pkd_hello` test is passing on an
OpenSSL 1.1.0 build for me. Previously it would segfault during
pubkey exchange with "ecdh-sha2-nistp256".
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
src/ecdh_crypto.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/ecdh_crypto.c b/src/ecdh_crypto.c
index 041e6c0e..24f21c03 100644
--- a/src/ecdh_crypto.c
+++ b/src/ecdh_crypto.c
@@ -206,6 +206,7 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
/* SSH host keys (rsa,dsa,ecdsa) */
ssh_key privkey;
ssh_string sig_blob = NULL;
+ ssh_string pubkey_blob = NULL;
int curve;
int len;
int rc;
@@ -289,14 +290,22 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet){
return SSH_ERROR;
}
+ rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
+ if (rc != SSH_OK) {
+ ssh_set_error(session, SSH_FATAL, "Could not export server public key");
+ ssh_string_free(sig_blob);
+ return SSH_ERROR;
+ }
+
rc = ssh_buffer_pack(session->out_buffer,
"bSSS",
SSH2_MSG_KEXDH_REPLY,
- session->next_crypto->server_pubkey, /* host's pubkey */
+ pubkey_blob, /* host's pubkey */
q_s_string, /* ecdh public key */
sig_blob); /* signature blob */
ssh_string_free(sig_blob);
+ ssh_string_free(pubkey_blob);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
--
2.14.1
From 41dba131d58e261e6477f183323222b980a8c95b Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 25 May 2018 03:29:06 -0700
Subject: [PATCH 03/27] ecdh: fix SSH_MSG_KEXDH_REPLY for libgcrypt
Ensure to provide the `ssh_string` pubkey blob to the buffer packing
routine when computing the SSH_MSG_KEXDH_REPLY message, rather than
the new `ssh_key` type.
Introduced with 16217454d576511f37f39c3169963629f9d5082f.
Testing done: with this change, the `pkd_hello` test is passing on a
libgcrypt build for me. Previously it would segfault during pubkey
exchange with "ecdh-sha2-nistp256".
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
src/ecdh_gcrypt.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/src/ecdh_gcrypt.c b/src/ecdh_gcrypt.c
index e4b73dc2..7bbccc25 100644
--- a/src/ecdh_gcrypt.c
+++ b/src/ecdh_gcrypt.c
@@ -268,6 +268,7 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet) {
/* SSH host keys (rsa,dsa,ecdsa) */
ssh_key privkey;
ssh_string sig_blob = NULL;
+ ssh_string pubkey_blob = NULL;
int rc = SSH_ERROR;
const char *curve = NULL;
@@ -333,14 +334,22 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet) {
goto out;
}
+ rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
+ if (rc != SSH_OK) {
+ ssh_set_error(session, SSH_FATAL, "Could not export server public key");
+ ssh_string_free(sig_blob);
+ goto out;
+ }
+
rc = ssh_buffer_pack(session->out_buffer,
"bSSS",
SSH2_MSG_KEXDH_REPLY,
- session->next_crypto->server_pubkey, /* host's pubkey */
+ pubkey_blob, /* host's pubkey */
q_s_string, /* ecdh public key */
sig_blob); /* signature blob */
ssh_string_free(sig_blob);
+ ssh_string_free(pubkey_blob);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
--
2.14.1
From b9661829539463f4ca1844d7f455927a8847a968 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 25 May 2018 03:39:21 -0700
Subject: [PATCH 04/27] ecdh: fix SSH_MSG_KEXDH_REPLY for mbedTLS
Ensure to provide the `ssh_string` pubkey blob to the buffer packing
routine when computing the SSH_MSG_KEXDH_REPLY message, rather than
the new `ssh_key` type.
Introduced with 16217454d576511f37f39c3169963629f9d5082f.
Testing done: with this change, the `pkd_hello` test is passing on a
mbedTLS build for me. Previously it would segfault during pubkey
exchange with "ecdh-sha2-nistp256".
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
src/ecdh_mbedcrypto.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
diff --git a/src/ecdh_mbedcrypto.c b/src/ecdh_mbedcrypto.c
index d4e7a774..aebc7bac 100644
--- a/src/ecdh_mbedcrypto.c
+++ b/src/ecdh_mbedcrypto.c
@@ -181,6 +181,7 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet)
mbedtls_ecp_group grp;
ssh_key privkey = NULL;
ssh_string sig_blob = NULL;
+ ssh_string pubkey_blob = NULL;
int rc;
mbedtls_ecp_group_id curve;
@@ -256,12 +257,21 @@ int ssh_server_ecdh_init(ssh_session session, ssh_buffer packet)
goto out;
}
+ rc = ssh_dh_get_next_server_publickey_blob(session, &pubkey_blob);
+ if (rc != SSH_OK) {
+ ssh_set_error(session, SSH_FATAL, "Could not export server public key");
+ ssh_string_free(sig_blob);
+ goto out;
+ }
+
rc = ssh_buffer_pack(session->out_buffer, "bSSS",
- SSH2_MSG_KEXDH_REPLY, session->next_crypto->server_pubkey,
- q_s_string,
- sig_blob);
+ SSH2_MSG_KEXDH_REPLY,
+ pubkey_blob, /* host's pubkey */
+ q_s_string, /* ecdh public key */
+ sig_blob); /* signature blob */
ssh_string_free(sig_blob);
+ ssh_string_free(pubkey_blob);
if (rc != SSH_OK) {
ssh_set_error_oom(session);
--
2.14.1
From 87b468bf41dafb2dfffbf6d8291ce5cc6b2e05bb Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 25 May 2018 03:42:59 -0700
Subject: [PATCH 05/27] tests: fix -Wunused-function warning in
torture_pki_ecdsa.c
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Wrap some function definitions with `HAVE_LIBCRYPTO` ifdefs to
match their usages in `torture_run_tests`.
Fixes this warning I observe when building locally:
torture_pki_ecdsa.c:341:13: warning:
‘torture_pki_ecdsa_write_privkey’ defined but not used
[-Wunused-function]
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
tests/unittests/torture_pki_ecdsa.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/tests/unittests/torture_pki_ecdsa.c b/tests/unittests/torture_pki_ecdsa.c
index 6587a60d..e9939d56 100644
--- a/tests/unittests/torture_pki_ecdsa.c
+++ b/tests/unittests/torture_pki_ecdsa.c
@@ -338,6 +338,7 @@ static void torture_pki_generate_key_ecdsa(void **state)
ssh_free(session);
}
+#ifdef HAVE_LIBCRYPTO
static void torture_pki_ecdsa_write_privkey(void **state)
{
ssh_key origkey;
@@ -412,6 +413,7 @@ static void torture_pki_ecdsa_write_privkey(void **state)
ssh_key_free(origkey);
ssh_key_free(privkey);
}
+#endif /* HAVE_LIBCRYPTO */
static void torture_pki_ecdsa_name(void **state, const char *expected_name)
{
--
2.14.1
From c7b3cdda8f2d50c035b35a505abd29d50415c95d Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 25 May 2018 03:52:25 -0700
Subject: [PATCH 06/27] dh: fix `ssh_get_pubkey_hash` indentation
Fix `ssh_get_pubkey_hash` indentation to use softabs
with 4 spaces. No change in behavior.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
src/dh.c | 75 ++++++++++++++++++++++++++++++++--------------------------------
1 file changed, 37 insertions(+), 38 deletions(-)
diff --git a/src/dh.c b/src/dh.c
index d2ddfabd..733c6e76 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -980,51 +980,50 @@ error:
* @deprecated Use ssh_get_publickey_hash()
*/
int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) {
- ssh_key pubkey = NULL;
- ssh_string pubkey_blob = NULL;
- MD5CTX ctx;
- unsigned char *h;
- int rc;
+ ssh_key pubkey = NULL;
+ ssh_string pubkey_blob = NULL;
+ MD5CTX ctx;
+ unsigned char *h;
+ int rc;
- if (session == NULL || hash == NULL) {
- return SSH_ERROR;
- }
- *hash = NULL;
- if (session->current_crypto == NULL ||
- session->current_crypto->server_pubkey == NULL){
- ssh_set_error(session,SSH_FATAL,"No current cryptographic context");
- return SSH_ERROR;
- }
+ if (session == NULL || hash == NULL) {
+ return SSH_ERROR;
+ }
+ *hash = NULL;
+ if (session->current_crypto == NULL ||
+ session->current_crypto->server_pubkey == NULL) {
+ ssh_set_error(session,SSH_FATAL,"No current cryptographic context");
+ return SSH_ERROR;
+ }
- h = calloc(MD5_DIGEST_LEN, sizeof(unsigned char));
- if (h == NULL) {
- return SSH_ERROR;
- }
+ h = calloc(MD5_DIGEST_LEN, sizeof(unsigned char));
+ if (h == NULL) {
+ return SSH_ERROR;
+ }
- ctx = md5_init();
- if (ctx == NULL) {
- SAFE_FREE(h);
- return SSH_ERROR;
- }
+ ctx = md5_init();
+ if (ctx == NULL) {
+ SAFE_FREE(h);
+ return SSH_ERROR;
+ }
- rc = ssh_get_server_publickey(session, &pubkey);
- if (rc != 0) {
- SAFE_FREE(h);
- return SSH_ERROR;
- }
+ rc = ssh_get_server_publickey(session, &pubkey);
+ if (rc != 0) {
+ SAFE_FREE(h);
+ return SSH_ERROR;
+ }
- rc = ssh_pki_export_pubkey_blob(pubkey,
- &pubkey_blob);
- ssh_key_free(pubkey);
- if (rc != 0) {
- }
- md5_update(ctx, ssh_string_data(pubkey_blob), ssh_string_len(pubkey_blob));
- ssh_string_free(pubkey_blob);
- md5_final(h, ctx);
+ rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob);
+ ssh_key_free(pubkey);
+ if (rc != 0) {
+ }
+ md5_update(ctx, ssh_string_data(pubkey_blob), ssh_string_len(pubkey_blob));
+ ssh_string_free(pubkey_blob);
+ md5_final(h, ctx);
- *hash = h;
+ *hash = h;
- return MD5_DIGEST_LEN;
+ return MD5_DIGEST_LEN;
}
/**
--
2.14.1
From 518a683bfaeb350e334d22980b486e67411090a1 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 25 May 2018 03:56:54 -0700
Subject: [PATCH 07/27] dh: fix two leaks in `ssh_get_pubkey_hash`
Fix two memory leaks in `ssh_get_pubkey_hash` for some error paths.
The local `h` buffer and `ctx` MD5 context each must be free'd for
the SSH_ERROR cases.
Introduced with 16217454d576511f37f39c3169963629f9d5082f.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
src/dh.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/src/dh.c b/src/dh.c
index 733c6e76..c3de5b99 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -1008,15 +1008,20 @@ int ssh_get_pubkey_hash(ssh_session session, unsigned char **hash) {
}
rc = ssh_get_server_publickey(session, &pubkey);
- if (rc != 0) {
+ if (rc != SSH_OK) {
+ md5_final(h, ctx);
SAFE_FREE(h);
return SSH_ERROR;
}
rc = ssh_pki_export_pubkey_blob(pubkey, &pubkey_blob);
ssh_key_free(pubkey);
- if (rc != 0) {
+ if (rc != SSH_OK) {
+ md5_final(h, ctx);
+ SAFE_FREE(h);
+ return SSH_ERROR;
}
+
md5_update(ctx, ssh_string_data(pubkey_blob), ssh_string_len(pubkey_blob));
ssh_string_free(pubkey_blob);
md5_final(h, ctx);
--
2.14.1
From 43a0d359fd558de656048ca5c4aad6fd08c6488a Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 25 May 2018 04:35:04 -0700
Subject: [PATCH 08/27] pkd: add_test pkd_hello_i1 for `make test`
Add an entry for a `pkd_hello_i1` test which runs one iteration
through each of the pkd algorithm combinations.
Testing done: now `make test` will run `pkd_hello -i1` which
completes in ~25 seconds on my local machine.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
tests/pkd/CMakeLists.txt | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/tests/pkd/CMakeLists.txt b/tests/pkd/CMakeLists.txt
index 07384341..ff23ba95 100644
--- a/tests/pkd/CMakeLists.txt
+++ b/tests/pkd/CMakeLists.txt
@@ -32,4 +32,12 @@ set(pkd_libs
add_executable(pkd_hello ${pkd_hello_src})
target_link_libraries(pkd_hello ${pkd_libs})
+#
+# pkd_hello_i1 runs only one iteration per algorithm combination for
+# sake of speeding up overall test run time. More iterations can be
+# specified with `-i` and may be helpful for chasing down bugs that
+# are not 100% reproducible.
+#
+add_test(pkd_hello_i1 ${CMAKE_CURRENT_BINARY_DIR}/pkd_hello -i1)
+
endif (WITH_SERVER AND UNIX AND NOT WIN32)
--
2.14.1
From fb0be6ee04b2e7724cb4b595666d7dd12d9f4a77 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 25 May 2018 06:09:03 -0700
Subject: [PATCH 09/27] pkd: run with SOCKET_WRAPPER_LIBRARY
Use the socket_wrapper preload shim when running the `pkd_hello`
test with `make test`. The end goal here is to get this test
running alongside normal tests in regular CI. Changes to do
this:
* Configure PKD_ENVIRONMENT for the `pkd_hello_i1` test in the
CMakeLists.txt file.
* Add a `--socket-wrapper-dir|-w` flag that is used to opt-in to
initializing a SOCKET_WRAPPER_DIR as expected by the socket_wrapper
library.
A runtime flag is used here to make it easy to run `pkd_hello`
with the socket_wrapper library while avoiding a hard dependency.
Testing done: observed socker_wrapper in effect with `strace`;
running `make test` uses the wrapper correctly on my local
machine.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
tests/pkd/CMakeLists.txt | 14 +++++++-
tests/pkd/pkd_daemon.h | 4 +++
tests/pkd/pkd_hello.c | 89 +++++++++++++++++++++++++++++++++++++++++++++++-
3 files changed, 105 insertions(+), 2 deletions(-)
diff --git a/tests/pkd/CMakeLists.txt b/tests/pkd/CMakeLists.txt
index ff23ba95..a07021ec 100644
--- a/tests/pkd/CMakeLists.txt
+++ b/tests/pkd/CMakeLists.txt
@@ -38,6 +38,18 @@ target_link_libraries(pkd_hello ${pkd_libs})
# specified with `-i` and may be helpful for chasing down bugs that
# are not 100% reproducible.
#
-add_test(pkd_hello_i1 ${CMAKE_CURRENT_BINARY_DIR}/pkd_hello -i1)
+add_test(pkd_hello_i1 ${CMAKE_CURRENT_BINARY_DIR}/pkd_hello -i1 -w /tmp/pkd_socket_wrapper_XXXXXX)
+
+#
+# Configure environment for cwrap socket wrapper.
+#
+find_package(socket_wrapper 1.1.5 REQUIRED)
+if (OSX)
+ set(PKD_ENVIRONMENT "DYLD_FORCE_FLAT_NAMESPACE=1;DYLD_INSERT_LIBRARIES=${SOCKET_WRAPPER_LIBRARY}")
+else ()
+ set(PKD_ENVIRONMENT "LD_PRELOAD=${SOCKET_WRAPPER_LIBRARY}")
+endif ()
+message(STATUS "PKD_ENVIRONMENT=${PKD_ENVIRONMENT}")
+set_property(TEST pkd_hello_i1 PROPERTY ENVIRONMENT ${PKD_ENVIRONMENT})
endif (WITH_SERVER AND UNIX AND NOT WIN32)
diff --git a/tests/pkd/pkd_daemon.h b/tests/pkd/pkd_daemon.h
index 7bdf894d..abb07acd 100644
--- a/tests/pkd/pkd_daemon.h
+++ b/tests/pkd/pkd_daemon.h
@@ -32,6 +32,10 @@ struct pkd_daemon_args {
const char *testname;
const char *testmatch;
unsigned int iterations;
+
+ struct {
+ const char *mkdtemp_str;
+ } socket_wrapper;
} opts;
};
diff --git a/tests/pkd/pkd_hello.c b/tests/pkd/pkd_hello.c
index e0c0cbf6..951bd7b1 100644
--- a/tests/pkd/pkd_hello.c
+++ b/tests/pkd/pkd_hello.c
@@ -1,13 +1,14 @@
/*
* pkd_hello.c --
*
- * (c) 2014, 2017 Jon Simons <jon@xxxxxxxxxxxxx>
+ * (c) 2014, 2017-2018 Jon Simons <jon@xxxxxxxxxxxxx>
*/
#include "config.h"
#include <setjmp.h> // for cmocka
#include <stdarg.h> // for cmocka
#include <stdio.h>
+#include <stdlib.h>
#include <unistd.h> // for cmocka
#include <cmocka.h>
@@ -51,6 +52,8 @@ static struct argp_option options[] = {
"Run each test for the given number of iterations (default is 10)", 0 },
{ "match", 'm', "testmatch", 0,
"Run all tests with the given string", 0 },
+ { "socket-wrapper-dir", 'w', "<mkdtemp-template>", 0,
+ "Run in socket-wrapper mode using the given mkdtemp directory template", 0 },
{ "stdout", 'o', NULL, 0,
"Emit pkd stdout messages", 0 },
{ "test", 't', "testname", 0,
@@ -87,6 +90,9 @@ static error_t parse_opt(int key, char *arg, struct argp_state *state) {
case 'v':
pkd_dargs.opts.libssh_log_level += 1;
break;
+ case 'w':
+ pkd_dargs.opts.socket_wrapper.mkdtemp_str = arg;
+ break;
default:
return ARGP_ERR_UNKNOWN;
}
@@ -651,6 +657,75 @@ static int pkd_run_tests(void) {
return rc;
}
+static int pkd_init_socket_wrapper(void) {
+ int rc = 0;
+ char *mkdtemp_str = NULL;
+
+ if (pkd_dargs.opts.socket_wrapper.mkdtemp_str == NULL) {
+ goto out;
+ }
+
+ mkdtemp_str = strdup(pkd_dargs.opts.socket_wrapper.mkdtemp_str);
+ if (mkdtemp_str == NULL) {
+ fprintf(stderr, "pkd_init_socket_wrapper strdup failed\n");
+ goto errstrdup;
+ }
+ pkd_dargs.opts.socket_wrapper.mkdtemp_str = mkdtemp_str;
+
+ if (mkdtemp(mkdtemp_str) == NULL) {
+ fprintf(stderr, "pkd_init_socket_wrapper mkdtemp '%s' failed\n", mkdtemp_str);
+ goto errmkdtemp;
+ }
+
+ if (setenv("SOCKET_WRAPPER_DIR", mkdtemp_str, 1) != 0) {
+ fprintf(stderr, "pkd_init_socket_wrapper setenv failed\n");
+ goto errsetenv;
+ }
+
+ goto out;
+errsetenv:
+errmkdtemp:
+ free(mkdtemp_str);
+errstrdup:
+ rc = -1;
+out:
+ return rc;
+}
+
+static int pkd_rmfiles(const char *path) {
+ char bin[1024] = { 0 };
+ snprintf(&bin[0], sizeof(bin), "rm -f %s/*", path);
+ return system_checked(bin);
+}
+
+static int pkd_cleanup_socket_wrapper(void) {
+ int rc = 0;
+
+ if (pkd_dargs.opts.socket_wrapper.mkdtemp_str == NULL) {
+ goto out;
+ }
+
+ /* clean up socket-wrapper unix domain sockets */
+ if (pkd_rmfiles(pkd_dargs.opts.socket_wrapper.mkdtemp_str) != 0) {
+ fprintf(stderr, "pkd_cleanup_socket_wrapper pkd_rmfiles '%s' failed\n",
+ pkd_dargs.opts.socket_wrapper.mkdtemp_str);
+ goto errrmfiles;
+ }
+
+ if (rmdir(pkd_dargs.opts.socket_wrapper.mkdtemp_str) != 0) {
+ fprintf(stderr, "pkd_cleanup_socket_wrapper rmdir '%s' failed\n",
+ pkd_dargs.opts.socket_wrapper.mkdtemp_str);
+ goto errrmdir;
+ }
+
+ goto out;
+errrmdir:
+errrmfiles:
+ rc = -1;
+out:
+ return rc;
+}
+
int main(int argc, char **argv) {
int i = 0;
int rc = 0;
@@ -670,6 +745,12 @@ int main(int argc, char **argv) {
(void) argc; (void) argv;
#endif /* HAVE_ARGP_H */
+ rc = pkd_init_socket_wrapper();
+ if (rc != 0) {
+ fprintf(stderr, "pkd_init_socket_wrapper failed: %d\n", rc);
+ goto out_finalize;
+ }
+
if (pkd_dargs.opts.list != 0) {
while (testmap[i].testname != NULL) {
printf("%s\n", testmap[i++].testname);
@@ -681,6 +762,12 @@ int main(int argc, char **argv) {
}
}
+ rc = pkd_cleanup_socket_wrapper();
+ if (rc != 0) {
+ fprintf(stderr, "pkd_cleanup_socket_wrapper failed: %d\n", rc);
+ }
+
+out_finalize:
rc = ssh_finalize();
if (rc != 0) {
fprintf(stderr, "ssh_finalize: %d\n", rc);
--
2.14.1
From 59360c0efa36ec882116612b6fab3d8221455d57 Mon Sep 17 00:00:00 2001
From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:51 -0600
Subject: [PATCH 10/27] external: Add ChaCha and Poly1305 implementations from
OpenSSH
Signed-off-by: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Reviewed-by: Andreas Schneider <asn@xxxxxxxxx>
---
ConfigureChecks.cmake | 1 +
config.h.cmake | 3 +
include/libssh/chacha.h | 32 +++++++
include/libssh/poly1305.h | 18 ++++
src/CMakeLists.txt | 2 +
src/external/chacha.c | 218 ++++++++++++++++++++++++++++++++++++++++++++++
src/external/poly1305.c | 156 +++++++++++++++++++++++++++++++++
7 files changed, 430 insertions(+)
create mode 100644 include/libssh/chacha.h
create mode 100644 include/libssh/poly1305.h
create mode 100644 src/external/chacha.c
create mode 100644 src/external/poly1305.c
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 4f0ecf8a..2e1348f1 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -56,6 +56,7 @@ check_include_file(pty.h HAVE_PTY_H)
check_include_file(utmp.h HAVE_UTMP_H)
check_include_file(termios.h HAVE_TERMIOS_H)
check_include_file(unistd.h HAVE_UNISTD_H)
+check_include_file(stdint.h HAVE_STDINT_H)
check_include_file(util.h HAVE_UTIL_H)
check_include_file(libutil.h HAVE_LIBUTIL_H)
check_include_file(sys/time.h HAVE_SYS_TIME_H)
diff --git a/config.h.cmake b/config.h.cmake
index 50a50ed7..e8786b1e 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -50,6 +50,9 @@
/* Define to 1 if you have the <unistd.h> header file. */
#cmakedefine HAVE_UNISTD_H 1
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H 1
+
/* Define to 1 if you have the <openssl/aes.h> header file. */
#cmakedefine HAVE_OPENSSL_AES_H 1
diff --git a/include/libssh/chacha.h b/include/libssh/chacha.h
new file mode 100644
index 00000000..84ff66a2
--- /dev/null
+++ b/include/libssh/chacha.h
@@ -0,0 +1,32 @@
+/* $OpenBSD: chacha.h,v 1.3 2014/05/02 03:27:54 djm Exp $ */
+
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+*/
+
+#ifndef CHACHA_H
+#define CHACHA_H
+
+struct chacha_ctx {
+ uint32_t input[16];
+};
+
+#define CHACHA_MINKEYLEN 16
+#define CHACHA_NONCELEN 8
+#define CHACHA_CTRLEN 8
+#define CHACHA_STATELEN (CHACHA_NONCELEN+CHACHA_CTRLEN)
+#define CHACHA_BLOCKLEN 64
+
+void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits)
+ __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)));
+void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr)
+ __attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN)))
+ __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN)));
+void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m,
+ uint8_t *c, uint32_t bytes)
+ __attribute__((__bounded__(__buffer__, 2, 4)))
+ __attribute__((__bounded__(__buffer__, 3, 4)));
+
+#endif /* CHACHA_H */
diff --git a/include/libssh/poly1305.h b/include/libssh/poly1305.h
new file mode 100644
index 00000000..7126ecbf
--- /dev/null
+++ b/include/libssh/poly1305.h
@@ -0,0 +1,18 @@
+/*
+ * Public Domain poly1305 from Andrew Moon
+ * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
+ */
+
+#ifndef POLY1305_H
+#define POLY1305_H
+
+#define POLY1305_KEYLEN 32
+#define POLY1305_TAGLEN 16
+
+void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen,
+ const uint8_t key[POLY1305_KEYLEN])
+ __attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN)))
+ __attribute__((__bounded__(__buffer__, 2, 3)))
+ __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN)));
+
+#endif /* POLY1305_H */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 7ecee06c..edbf3520 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -158,9 +158,11 @@ set(libssh_SRCS
wrapper.c
external/bcrypt_pbkdf.c
external/blowfish.c
+ external/chacha.c
external/ed25519.c
external/fe25519.c
external/ge25519.c
+ external/poly1305.c
external/sc25519.c
)
diff --git a/src/external/chacha.c b/src/external/chacha.c
new file mode 100644
index 00000000..062aafb8
--- /dev/null
+++ b/src/external/chacha.c
@@ -0,0 +1,218 @@
+/*
+chacha-merged.c version 20080118
+D. J. Bernstein
+Public domain.
+ */
+
+#include <stdint.h>
+#include <unistd.h>
+#include <sys/types.h>
+
+#include "libssh/chacha.h"
+
+typedef unsigned int uint32_t;
+
+typedef struct chacha_ctx chacha_ctx;
+
+#define U8C(v) (v##U)
+#define U32C(v) (v##U)
+
+#define U8V(v) ((uint8_t)(v) & U8C(0xFF))
+#define U32V(v) ((uint32_t)(v) & U32C(0xFFFFFFFF))
+
+#define ROTL32(v, n) \
+ (U32V((v) << (n)) | ((v) >> (32 - (n))))
+
+#define U8TO32_LITTLE(p) \
+ (((uint32_t)((p)[0]) ) | \
+ ((uint32_t)((p)[1]) << 8) | \
+ ((uint32_t)((p)[2]) << 16) | \
+ ((uint32_t)((p)[3]) << 24))
+
+#define U32TO8_LITTLE(p, v) \
+ do { \
+ (p)[0] = U8V((v) ); \
+ (p)[1] = U8V((v) >> 8); \
+ (p)[2] = U8V((v) >> 16); \
+ (p)[3] = U8V((v) >> 24); \
+ } while (0)
+
+#define ROTATE(v,c) (ROTL32(v,c))
+#define XOR(v,w) ((v) ^ (w))
+#define PLUS(v,w) (U32V((v) + (w)))
+#define PLUSONE(v) (PLUS((v),1))
+
+#define QUARTERROUND(a,b,c,d) \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
+ a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
+ c = PLUS(c,d); b = ROTATE(XOR(b,c), 7);
+
+static const char sigma[16] = "expand 32-byte k";
+static const char tau[16] = "expand 16-byte k";
+
+void
+chacha_keysetup(chacha_ctx *x,const uint8_t *k,uint32_t kbits)
+{
+ const char *constants;
+
+ x->input[4] = U8TO32_LITTLE(k + 0);
+ x->input[5] = U8TO32_LITTLE(k + 4);
+ x->input[6] = U8TO32_LITTLE(k + 8);
+ x->input[7] = U8TO32_LITTLE(k + 12);
+ if (kbits == 256) { /* recommended */
+ k += 16;
+ constants = sigma;
+ } else { /* kbits == 128 */
+ constants = tau;
+ }
+ x->input[8] = U8TO32_LITTLE(k + 0);
+ x->input[9] = U8TO32_LITTLE(k + 4);
+ x->input[10] = U8TO32_LITTLE(k + 8);
+ x->input[11] = U8TO32_LITTLE(k + 12);
+ x->input[0] = U8TO32_LITTLE(constants + 0);
+ x->input[1] = U8TO32_LITTLE(constants + 4);
+ x->input[2] = U8TO32_LITTLE(constants + 8);
+ x->input[3] = U8TO32_LITTLE(constants + 12);
+}
+
+void
+chacha_ivsetup(chacha_ctx *x, const uint8_t *iv, const uint8_t *counter)
+{
+ x->input[12] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 0);
+ x->input[13] = counter == NULL ? 0 : U8TO32_LITTLE(counter + 4);
+ x->input[14] = U8TO32_LITTLE(iv + 0);
+ x->input[15] = U8TO32_LITTLE(iv + 4);
+}
+
+void
+chacha_encrypt_bytes(chacha_ctx *x,const uint8_t *m,uint8_t *c,uint32_t bytes)
+{
+ uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15;
+ uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15;
+ uint8_t *ctarget = NULL;
+ uint8_t tmp[64];
+ u_int i;
+
+ if (!bytes) return;
+
+ j0 = x->input[0];
+ j1 = x->input[1];
+ j2 = x->input[2];
+ j3 = x->input[3];
+ j4 = x->input[4];
+ j5 = x->input[5];
+ j6 = x->input[6];
+ j7 = x->input[7];
+ j8 = x->input[8];
+ j9 = x->input[9];
+ j10 = x->input[10];
+ j11 = x->input[11];
+ j12 = x->input[12];
+ j13 = x->input[13];
+ j14 = x->input[14];
+ j15 = x->input[15];
+
+ for (;;) {
+ if (bytes < 64) {
+ for (i = 0;i < bytes;++i) tmp[i] = m[i];
+ m = tmp;
+ ctarget = c;
+ c = tmp;
+ }
+ x0 = j0;
+ x1 = j1;
+ x2 = j2;
+ x3 = j3;
+ x4 = j4;
+ x5 = j5;
+ x6 = j6;
+ x7 = j7;
+ x8 = j8;
+ x9 = j9;
+ x10 = j10;
+ x11 = j11;
+ x12 = j12;
+ x13 = j13;
+ x14 = j14;
+ x15 = j15;
+ for (i = 20;i > 0;i -= 2) {
+ QUARTERROUND( x0, x4, x8,x12)
+ QUARTERROUND( x1, x5, x9,x13)
+ QUARTERROUND( x2, x6,x10,x14)
+ QUARTERROUND( x3, x7,x11,x15)
+ QUARTERROUND( x0, x5,x10,x15)
+ QUARTERROUND( x1, x6,x11,x12)
+ QUARTERROUND( x2, x7, x8,x13)
+ QUARTERROUND( x3, x4, x9,x14)
+ }
+ x0 = PLUS(x0,j0);
+ x1 = PLUS(x1,j1);
+ x2 = PLUS(x2,j2);
+ x3 = PLUS(x3,j3);
+ x4 = PLUS(x4,j4);
+ x5 = PLUS(x5,j5);
+ x6 = PLUS(x6,j6);
+ x7 = PLUS(x7,j7);
+ x8 = PLUS(x8,j8);
+ x9 = PLUS(x9,j9);
+ x10 = PLUS(x10,j10);
+ x11 = PLUS(x11,j11);
+ x12 = PLUS(x12,j12);
+ x13 = PLUS(x13,j13);
+ x14 = PLUS(x14,j14);
+ x15 = PLUS(x15,j15);
+
+ x0 = XOR(x0,U8TO32_LITTLE(m + 0));
+ x1 = XOR(x1,U8TO32_LITTLE(m + 4));
+ x2 = XOR(x2,U8TO32_LITTLE(m + 8));
+ x3 = XOR(x3,U8TO32_LITTLE(m + 12));
+ x4 = XOR(x4,U8TO32_LITTLE(m + 16));
+ x5 = XOR(x5,U8TO32_LITTLE(m + 20));
+ x6 = XOR(x6,U8TO32_LITTLE(m + 24));
+ x7 = XOR(x7,U8TO32_LITTLE(m + 28));
+ x8 = XOR(x8,U8TO32_LITTLE(m + 32));
+ x9 = XOR(x9,U8TO32_LITTLE(m + 36));
+ x10 = XOR(x10,U8TO32_LITTLE(m + 40));
+ x11 = XOR(x11,U8TO32_LITTLE(m + 44));
+ x12 = XOR(x12,U8TO32_LITTLE(m + 48));
+ x13 = XOR(x13,U8TO32_LITTLE(m + 52));
+ x14 = XOR(x14,U8TO32_LITTLE(m + 56));
+ x15 = XOR(x15,U8TO32_LITTLE(m + 60));
+
+ j12 = PLUSONE(j12);
+ if (!j12) {
+ j13 = PLUSONE(j13);
+ /* stopping at 2^70 bytes per nonce is user's responsibility */
+ }
+
+ U32TO8_LITTLE(c + 0,x0);
+ U32TO8_LITTLE(c + 4,x1);
+ U32TO8_LITTLE(c + 8,x2);
+ U32TO8_LITTLE(c + 12,x3);
+ U32TO8_LITTLE(c + 16,x4);
+ U32TO8_LITTLE(c + 20,x5);
+ U32TO8_LITTLE(c + 24,x6);
+ U32TO8_LITTLE(c + 28,x7);
+ U32TO8_LITTLE(c + 32,x8);
+ U32TO8_LITTLE(c + 36,x9);
+ U32TO8_LITTLE(c + 40,x10);
+ U32TO8_LITTLE(c + 44,x11);
+ U32TO8_LITTLE(c + 48,x12);
+ U32TO8_LITTLE(c + 52,x13);
+ U32TO8_LITTLE(c + 56,x14);
+ U32TO8_LITTLE(c + 60,x15);
+
+ if (bytes <= 64) {
+ if (bytes < 64) {
+ for (i = 0;i < bytes;++i) ctarget[i] = c[i];
+ }
+ x->input[12] = j12;
+ x->input[13] = j13;
+ return;
+ }
+ bytes -= 64;
+ c += 64;
+ m += 64;
+ }
+}
diff --git a/src/external/poly1305.c b/src/external/poly1305.c
new file mode 100644
index 00000000..916dd625
--- /dev/null
+++ b/src/external/poly1305.c
@@ -0,0 +1,156 @@
+/*
+ * Public Domain poly1305 from Andrew Moon
+ * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna
+ */
+
+#include "config.h"
+
+#include <stdint.h>
+#include <sys/types.h>
+
+#include "libssh/poly1305.h"
+
+#define mul32x32_64(a,b) ((uint64_t)(a) * (b))
+
+#define U8TO32_LE(p) \
+ (((uint32_t)((p)[0])) | \
+ ((uint32_t)((p)[1]) << 8) | \
+ ((uint32_t)((p)[2]) << 16) | \
+ ((uint32_t)((p)[3]) << 24))
+
+#define U32TO8_LE(p, v) \
+ do { \
+ (p)[0] = (uint8_t)((v)); \
+ (p)[1] = (uint8_t)((v) >> 8); \
+ (p)[2] = (uint8_t)((v) >> 16); \
+ (p)[3] = (uint8_t)((v) >> 24); \
+ } while (0)
+
+void
+poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) {
+ uint32_t t0,t1,t2,t3;
+ uint32_t h0,h1,h2,h3,h4;
+ uint32_t r0,r1,r2,r3,r4;
+ uint32_t s1,s2,s3,s4;
+ uint32_t b, nb;
+ size_t j;
+ uint64_t t[5];
+ uint64_t f0,f1,f2,f3;
+ uint32_t g0,g1,g2,g3,g4;
+ uint64_t c;
+ unsigned char mp[16];
+
+ /* clamp key */
+ t0 = U8TO32_LE(key+0);
+ t1 = U8TO32_LE(key+4);
+ t2 = U8TO32_LE(key+8);
+ t3 = U8TO32_LE(key+12);
+
+ /* precompute multipliers */
+ r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6;
+ r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12;
+ r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18;
+ r3 = t2 & 0x3f03fff; t3 >>= 8;
+ r4 = t3 & 0x00fffff;
+
+ s1 = r1 * 5;
+ s2 = r2 * 5;
+ s3 = r3 * 5;
+ s4 = r4 * 5;
+
+ /* init state */
+ h0 = 0;
+ h1 = 0;
+ h2 = 0;
+ h3 = 0;
+ h4 = 0;
+
+ /* full blocks */
+ if (inlen < 16) goto poly1305_donna_atmost15bytes;
+poly1305_donna_16bytes:
+ m += 16;
+ inlen -= 16;
+
+ t0 = U8TO32_LE(m-16);
+ t1 = U8TO32_LE(m-12);
+ t2 = U8TO32_LE(m-8);
+ t3 = U8TO32_LE(m-4);
+
+ h0 += t0 & 0x3ffffff;
+ h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
+ h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
+ h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
+ h4 += (t3 >> 8) | (1 << 24);
+
+
+poly1305_donna_mul:
+ t[0] = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1);
+ t[1] = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2);
+ t[2] = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3);
+ t[3] = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4);
+ t[4] = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0);
+
+ h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26);
+ t[1] += c; h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26);
+ t[2] += b; h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26);
+ t[3] += b; h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26);
+ t[4] += b; h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26);
+ h0 += b * 5;
+
+ if (inlen >= 16) goto poly1305_donna_16bytes;
+
+ /* final bytes */
+poly1305_donna_atmost15bytes:
+ if (!inlen) goto poly1305_donna_finish;
+
+ for (j = 0; j < inlen; j++) mp[j] = m[j];
+ mp[j++] = 1;
+ for (; j < 16; j++) mp[j] = 0;
+ inlen = 0;
+
+ t0 = U8TO32_LE(mp+0);
+ t1 = U8TO32_LE(mp+4);
+ t2 = U8TO32_LE(mp+8);
+ t3 = U8TO32_LE(mp+12);
+
+ h0 += t0 & 0x3ffffff;
+ h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff;
+ h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff;
+ h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff;
+ h4 += (t3 >> 8);
+
+ goto poly1305_donna_mul;
+
+poly1305_donna_finish:
+ b = h0 >> 26; h0 = h0 & 0x3ffffff;
+ h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff;
+ h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff;
+ h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff;
+ h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff;
+ h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff;
+ h1 += b;
+
+ g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff;
+ g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff;
+ g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff;
+ g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff;
+ g4 = h4 + b - (1 << 26);
+
+ b = (g4 >> 31) - 1;
+ nb = ~b;
+ h0 = (h0 & nb) | (g0 & b);
+ h1 = (h1 & nb) | (g1 & b);
+ h2 = (h2 & nb) | (g2 & b);
+ h3 = (h3 & nb) | (g3 & b);
+ h4 = (h4 & nb) | (g4 & b);
+
+ f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]);
+ f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]);
+ f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]);
+ f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]);
+
+ U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32);
+ U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32);
+ U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32);
+ U32TO8_LE(&out[12], f3);
+}
--
2.14.1
From b59ec47b8672759490507194f29b33ae22ac5cd3 Mon Sep 17 00:00:00 2001
From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:52 -0600
Subject: [PATCH 11/27] cmake: detect "bounded" compiler attribute
Signed-off-by: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Reviewed-by: Andreas Schneider <asn@xxxxxxxxxxxxxx>
---
ConfigureChecks.cmake | 5 +++++
config.h.cmake | 2 ++
include/libssh/chacha.h | 15 ++++++++++++---
include/libssh/poly1305.h | 5 ++++-
4 files changed, 23 insertions(+), 4 deletions(-)
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index 2e1348f1..fd8ff136 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -327,6 +327,11 @@ int main(void) {
}" HAVE_COMPILER__FUNCTION__)
+check_c_source_compiles("
+void chacha_keysetup(struct chacha_ctx *x, const u_char *k, u_int kbits)
+ __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)));
+int main(void) { return 0; }" HAVE_GCC_BOUNDED_ATTRIBUTE)
+
if (WITH_DEBUG_CRYPTO)
set(DEBUG_CRYPTO 1)
endif (WITH_DEBUG_CRYPTO)
diff --git a/config.h.cmake b/config.h.cmake
index e8786b1e..61d20acb 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -199,6 +199,8 @@
#cmakedefine HAVE_COMPILER__FUNC__ 1
#cmakedefine HAVE_COMPILER__FUNCTION__ 1
+#cmakedefine HAVE_GCC_BOUNDED_ATTRIBUTE 1
+
/* Define to 1 if you want to enable GSSAPI */
#cmakedefine WITH_GSSAPI 1
diff --git a/include/libssh/chacha.h b/include/libssh/chacha.h
index 84ff66a2..bac78c67 100644
--- a/include/libssh/chacha.h
+++ b/include/libssh/chacha.h
@@ -20,13 +20,22 @@ struct chacha_ctx {
#define CHACHA_BLOCKLEN 64
void chacha_keysetup(struct chacha_ctx *x, const uint8_t *k, uint32_t kbits)
- __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)));
+#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
+ __attribute__((__bounded__(__minbytes__, 2, CHACHA_MINKEYLEN)))
+#endif
+ ;
void chacha_ivsetup(struct chacha_ctx *x, const uint8_t *iv, const uint8_t *ctr)
+#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
__attribute__((__bounded__(__minbytes__, 2, CHACHA_NONCELEN)))
- __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN)));
+ __attribute__((__bounded__(__minbytes__, 3, CHACHA_CTRLEN)))
+#endif
+ ;
void chacha_encrypt_bytes(struct chacha_ctx *x, const uint8_t *m,
uint8_t *c, uint32_t bytes)
+#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
__attribute__((__bounded__(__buffer__, 2, 4)))
- __attribute__((__bounded__(__buffer__, 3, 4)));
+ __attribute__((__bounded__(__buffer__, 3, 4)))
+#endif
+ ;
#endif /* CHACHA_H */
diff --git a/include/libssh/poly1305.h b/include/libssh/poly1305.h
index 7126ecbf..9174bd17 100644
--- a/include/libssh/poly1305.h
+++ b/include/libssh/poly1305.h
@@ -11,8 +11,11 @@
void poly1305_auth(uint8_t out[POLY1305_TAGLEN], const uint8_t *m, size_t inlen,
const uint8_t key[POLY1305_KEYLEN])
+#ifdef HAVE_GCC_BOUNDED_ATTRIBUTE
__attribute__((__bounded__(__minbytes__, 1, POLY1305_TAGLEN)))
__attribute__((__bounded__(__buffer__, 2, 3)))
- __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN)));
+ __attribute__((__bounded__(__minbytes__, 4, POLY1305_KEYLEN)))
+#endif
+ ;
#endif /* POLY1305_H */
--
2.14.1
From 3241d735f9b948b50c4ce81435385141045283e0 Mon Sep 17 00:00:00 2001
From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:53 -0600
Subject: [PATCH 12/27] chacha: packet encryption
Signed-off-by: Aris Adamantiadis <aris@xxxxxxxxxxxx>
---
include/libssh/crypto.h | 6 +++
include/libssh/libcrypto.h | 1 +
include/libssh/wrapper.h | 3 +-
src/CMakeLists.txt | 1 +
src/chachapoly.c | 126 +++++++++++++++++++++++++++++++++++++++++++++
src/dh.c | 3 ++
src/kex.c | 4 +-
src/libcrypto.c | 21 +++++++-
src/packet.c | 43 +++++++++++-----
src/packet_crypt.c | 46 ++++++++++-------
src/wrapper.c | 96 ++++++++++++++++++++++++----------
11 files changed, 288 insertions(+), 62 deletions(-)
create mode 100644 src/chachapoly.c
diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h
index fab39ed1..e6e5b8f6 100644
--- a/include/libssh/crypto.h
+++ b/include/libssh/crypto.h
@@ -128,10 +128,12 @@ struct ssh_cipher_struct {
const char *name; /* ssh name of the algorithm */
unsigned int blocksize; /* blocksize of the algo */
enum ssh_cipher_e ciphertype;
+ uint32_t lenfield_blocksize; /* blocksize of the packet length field */
#ifdef HAVE_LIBGCRYPT
size_t keylen; /* length of the key structure */
gcry_cipher_hd_t *key;
#elif defined HAVE_LIBCRYPTO
+ size_t keylen; /* length of the key structure */
struct ssh_3des_key_schedule *des3_key;
struct ssh_aes_key_schedule *aes_key;
const EVP_CIPHER *cipher;
@@ -141,7 +143,9 @@ struct ssh_cipher_struct {
mbedtls_cipher_context_t decrypt_ctx;
mbedtls_cipher_type_t type;
#endif
+ struct chacha20_poly1305_keysched *chacha20_schedule;
unsigned int keysize; /* bytes of key used. != keylen */
+ size_t tag_size; /* overhead required for tag */
/* sets the new key for immediate use */
int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
@@ -149,6 +153,8 @@ struct ssh_cipher_struct {
unsigned long len);
void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
unsigned long len);
+ void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
+ size_t len, uint8_t *mac, uint64_t seq);
void (*cleanup)(struct ssh_cipher_struct *cipher);
};
diff --git a/include/libssh/libcrypto.h b/include/libssh/libcrypto.h
index 6a08837a..4b8e5414 100644
--- a/include/libssh/libcrypto.h
+++ b/include/libssh/libcrypto.h
@@ -95,6 +95,7 @@ SHA512CTX sha512_init(void);
void sha512_update(SHA512CTX c, const void *data, unsigned long len);
void sha512_final(unsigned char *md, SHA512CTX c);
+void libcrypto_init(void);
struct ssh_cipher_struct *ssh_get_ciphertab(void);
#endif /* HAVE_LIBCRYPTO */
diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h
index 6b6cf0b1..c23c9061 100644
--- a/include/libssh/wrapper.h
+++ b/include/libssh/wrapper.h
@@ -39,7 +39,8 @@ enum ssh_hmac_e {
SSH_HMAC_SHA256,
SSH_HMAC_SHA384,
SSH_HMAC_SHA512,
- SSH_HMAC_MD5
+ SSH_HMAC_MD5,
+ SSH_HMAC_AEAD_POLY1305
};
enum ssh_des_e {
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index edbf3520..90e44253 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -122,6 +122,7 @@ set(libssh_SRCS
bignum.c
buffer.c
callbacks.c
+ chachapoly.c
channels.c
client.c
config.c
diff --git a/src/chachapoly.c b/src/chachapoly.c
new file mode 100644
index 00000000..16032179
--- /dev/null
+++ b/src/chachapoly.c
@@ -0,0 +1,126 @@
+/*
+ * This file is part of the SSH Library
+ *
+ * Copyright (c) 2015 by Aris Adamantiadis
+ *
+ * The SSH Library is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or (at your
+ * option) any later version.
+ *
+ * The SSH Library is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
+ * License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with the SSH Library; see the file COPYING. If not, write to
+ * the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "libssh/libssh.h"
+#include "libssh/crypto.h"
+#include "libssh/chacha.h"
+#include "libssh/poly1305.h"
+#include "libssh/misc.h"
+
+/* size of the keys k1 and k2 as defined in specs */
+#define CHACHA20_KEYLEN 32
+struct chacha20_poly1305_keysched {
+ /* key used for encrypting the length field*/
+ struct chacha_ctx k1;
+ /* key used for encrypting the packets */
+ struct chacha_ctx k2;
+};
+
+#pragma pack(push, 1)
+struct ssh_packet_header {
+ uint32_t length;
+ uint8_t payload[];
+};
+#pragma pack(pop)
+
+const uint8_t zero_block_counter[8] = {0, 0, 0, 0, 0, 0, 0, 0};
+const uint8_t payload_block_counter[8] = {1, 0, 0, 0, 0, 0, 0, 0};
+
+static int chacha20_set_encrypt_key(struct ssh_cipher_struct *cipher,
+ void *key,
+ void *IV)
+{
+ struct chacha20_poly1305_keysched *sched;
+ uint8_t *u8key = key;
+ (void)IV;
+
+ if (cipher->chacha20_schedule == NULL) {
+ sched = malloc(sizeof *sched);
+ if (sched == NULL){
+ return -1;
+ }
+ } else {
+ sched = cipher->chacha20_schedule;
+ }
+
+ chacha_keysetup(&sched->k2, u8key, CHACHA20_KEYLEN * 8);
+ chacha_keysetup(&sched->k1, u8key + CHACHA20_KEYLEN, CHACHA20_KEYLEN * 8);
+ cipher->chacha20_schedule = sched;
+
+ return 0;
+}
+
+/**
+ * @internal
+ *
+ * @brief encrypts an outgoing packet with chacha20 and authenticate it
+ * with poly1305.
+ */
+static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
+ void *in,
+ void *out,
+ size_t len,
+ uint8_t *tag,
+ uint64_t seq)
+{
+ struct ssh_packet_header *in_packet = in, *out_packet = out;
+ uint8_t poly1305_ctx[POLY1305_KEYLEN] = {0};
+ struct chacha20_poly1305_keysched *keys = cipher->chacha20_schedule;
+
+ seq = htonll(seq);
+ /* step 1, prepare the poly1305 key */
+ chacha_ivsetup(&keys->k2, (uint8_t *)&seq, zero_block_counter);
+ chacha_encrypt_bytes(&keys->k2,
+ poly1305_ctx,
+ poly1305_ctx,
+ POLY1305_KEYLEN);
+
+ /* step 2, encrypt length field */
+ chacha_ivsetup(&keys->k1, (uint8_t *)&seq, zero_block_counter);
+ chacha_encrypt_bytes(&keys->k1,
+ (uint8_t *)&in_packet->length,
+ (uint8_t *)&out_packet->length,
+ sizeof(uint32_t));
+
+ /* step 3, encrypt packet payload */
+ chacha_ivsetup(&keys->k2, (uint8_t *)&seq, payload_block_counter);
+ chacha_encrypt_bytes(&keys->k2,
+ in_packet->payload,
+ out_packet->payload,
+ len - sizeof(uint32_t));
+
+ /* step 4, compute the MAC */
+ poly1305_auth(tag, (uint8_t *)out_packet, len, poly1305_ctx);
+}
+
+const struct ssh_cipher_struct chacha20poly1305_cipher = {
+ .name = "chacha20-poly1305@xxxxxxxxxxx",
+ .blocksize = 8,
+ .lenfield_blocksize = 4,
+ .keylen = sizeof(struct chacha20_poly1305_keysched),
+ .keysize = 512,
+ .tag_size = POLY1305_TAGLEN,
+ .set_encrypt_key = chacha20_set_encrypt_key,
+ .set_decrypt_key = chacha20_set_encrypt_key,
+ .aead_encrypt = chacha20_poly1305_aead_encrypt,
+};
diff --git a/src/dh.c b/src/dh.c
index c3de5b99..2bc0a9d6 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -68,6 +68,7 @@
#include <openssl/rand.h>
#include <openssl/evp.h>
#include <openssl/err.h>
+#include "libssh/libcrypto.h"
#endif
static unsigned char p_group1_value[] = {
@@ -210,6 +211,8 @@ int ssh_crypto_init(void) {
bignum_bin2bn(p_group14_value, P_GROUP14_LEN, p_group14);
OpenSSL_add_all_algorithms();
+
+ libcrypto_init();
#elif defined HAVE_LIBMBEDCRYPTO
p_group1 = bignum_new();
bignum_bin2bn(p_group1_value, P_GROUP1_LEN, p_group1);
diff --git a/src/kex.c b/src/kex.c
index b658ed44..20044c32 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -95,6 +95,8 @@
#define ECDH ""
#endif
+#define CHACHA20 "chacha20-poly1305@xxxxxxxxxxx,"
+
#define KEY_EXCHANGE CURVE25519 ECDH "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
#define KEX_METHODS_SIZE 10
@@ -117,7 +119,7 @@ static const char *default_methods[] = {
static const char *supported_methods[] = {
KEY_EXCHANGE,
HOSTKEYS,
- AES BLOWFISH DES_SUPPORTED,
+ CHACHA20 AES BLOWFISH DES_SUPPORTED,
AES BLOWFISH DES_SUPPORTED,
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
diff --git a/src/libcrypto.c b/src/libcrypto.c
index 66453666..982c9c84 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -60,6 +60,7 @@
#include "libssh/crypto.h"
+extern const struct ssh_cipher_struct chacha20poly1305_cipher;
struct ssh_mac_ctx_struct {
enum ssh_mac_e mac_type;
union {
@@ -860,11 +861,30 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.cleanup = des_cleanup
},
#endif /* HAS_DES */
+ {
+ .name = "chacha20-poly1305@xxxxxxxxxxx"
+ },
{
.name = NULL
}
};
+void libcrypto_init(void)
+{
+ size_t i;
+
+ for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
+ int cmp;
+
+ cmp = strcmp(ssh_ciphertab[i].name, "chacha20-poly1305@xxxxxxxxxxx");
+ if (cmp == 0) {
+ memcpy(&ssh_ciphertab[i],
+ &chacha20poly1305_cipher,
+ sizeof(struct ssh_cipher_struct));
+ break;
+ }
+ }
+}
struct ssh_cipher_struct *ssh_get_ciphertab(void)
{
@@ -872,4 +892,3 @@ struct ssh_cipher_struct *ssh_get_ciphertab(void)
}
#endif /* LIBCRYPTO */
-
diff --git a/src/packet.c b/src/packet.c
index b66e3d22..f6fb6bff 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -555,6 +555,8 @@ static int ssh_packet_write(ssh_session session) {
static int packet_send2(ssh_session session) {
unsigned int blocksize = (session->current_crypto ?
session->current_crypto->out_cipher->blocksize : 8);
+ unsigned int lenfield_blocksize = (session->current_crypto ?
+ session->current_crypto->out_cipher->lenfield_blocksize : 0);
enum ssh_hmac_e hmac_type = (session->current_crypto ?
session->current_crypto->out_hmac : session->next_crypto->out_hmac);
uint32_t currentlen = ssh_buffer_get_len(session->out_buffer);
@@ -563,8 +565,7 @@ static int packet_send2(ssh_session session) {
int rc = SSH_ERROR;
uint32_t finallen,payloadsize,compsize;
uint8_t padding;
-
- uint8_t header[sizeof(padding) + sizeof(finallen)] = { 0 };
+ ssh_buffer header_buffer = ssh_buffer_new();
payloadsize = currentlen;
#ifdef WITH_ZLIB
@@ -578,20 +579,30 @@ static int packet_send2(ssh_session session) {
}
#endif /* WITH_ZLIB */
compsize = currentlen;
- padding = (blocksize - ((currentlen +5) % blocksize));
+ /* compressed payload + packet len (4) + padding len (1) */
+ /* totallen - lenfield_blocksize must be equal to 0 (mod blocksize) */
+ padding = (blocksize - ((blocksize - lenfield_blocksize + currentlen + 5) % blocksize));
if(padding < 4) {
padding += blocksize;
}
- if (session->current_crypto) {
+ if (session->current_crypto != NULL) {
ssh_get_random(padstring, padding, 0);
}
- finallen = htonl(currentlen + padding + 1);
+ if (header_buffer == NULL){
+ ssh_set_error_oom(session);
+ goto error;
+ }
+ finallen = currentlen + padding + 1;
+ rc = ssh_buffer_pack(header_buffer, "db", finallen, padding);
+ if (rc == SSH_ERROR){
+ goto error;
+ }
- memcpy(&header[0], &finallen, sizeof(finallen));
- header[sizeof(finallen)] = padding;
- rc = ssh_buffer_prepend_data(session->out_buffer, &header, sizeof(header));
+ rc = ssh_buffer_prepend_data(session->out_buffer,
+ ssh_buffer_get(header_buffer),
+ ssh_buffer_get_len(header_buffer));
if (rc < 0) {
goto error;
}
@@ -600,10 +611,12 @@ static int packet_send2(ssh_session session) {
goto error;
}
#ifdef WITH_PCAP
- if(session->pcap_ctx){
- ssh_pcap_context_write(session->pcap_ctx,SSH_PCAP_DIR_OUT,
- ssh_buffer_get(session->out_buffer),ssh_buffer_get_len(session->out_buffer)
- ,ssh_buffer_get_len(session->out_buffer));
+ if (session->pcap_ctx) {
+ ssh_pcap_context_write(session->pcap_ctx,
+ SSH_PCAP_DIR_OUT,
+ ssh_buffer_get(session->out_buffer),
+ ssh_buffer_get_len(session->out_buffer),
+ ssh_buffer_get_len(session->out_buffer));
}
#endif
hmac = ssh_packet_encrypt(session, ssh_buffer_get(session->out_buffer),
@@ -624,12 +637,14 @@ static int packet_send2(ssh_session session) {
SSH_LOG(SSH_LOG_PACKET,
"packet: wrote [len=%d,padding=%hhd,comp=%d,payload=%d]",
- ntohl(finallen), padding, compsize, payloadsize);
+ finallen, padding, compsize, payloadsize);
if (ssh_buffer_reinit(session->out_buffer) < 0) {
rc = SSH_ERROR;
}
error:
-
+ if (header_buffer != NULL) {
+ ssh_buffer_free(header_buffer);
+ }
return rc; /* SSH_OK, AGAIN or ERROR */
}
diff --git a/src/packet_crypt.c b/src/packet_crypt.c
index 7a30e661..5bcb6d65 100644
--- a/src/packet_crypt.c
+++ b/src/packet_crypt.c
@@ -93,7 +93,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
if (!session->current_crypto) {
return NULL; /* nothing to do here */
}
- if(len % session->current_crypto->in_cipher->blocksize != 0){
+ if((len - session->current_crypto->out_cipher->lenfield_blocksize) % session->current_crypto->out_cipher->blocksize != 0){
ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
return NULL;
}
@@ -106,26 +106,36 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
seq = ntohl(session->send_seq);
crypto = session->current_crypto->out_cipher;
- if (session->version == 2) {
- ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type);
- if (ctx == NULL) {
- SAFE_FREE(out);
- return NULL;
- }
- hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t));
- hmac_update(ctx,data,len);
- hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
+ if (crypto->aead_encrypt != NULL) {
+ crypto->aead_encrypt(crypto, data, out, len,
+ session->current_crypto->hmacbuf, session->send_seq);
+ } else {
+ if (session->version == 2) {
+ ctx = hmac_init(session->current_crypto->encryptMAC, hmac_digest_len(type), type);
+ if (ctx == NULL) {
+ SAFE_FREE(out);
+ return NULL;
+ }
+ hmac_update(ctx,(unsigned char *)&seq,sizeof(uint32_t));
+ hmac_update(ctx,data,len);
+ hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
+
+ if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey,
+ session->current_crypto->encryptIV) < 0) {
+ SAFE_FREE(out);
+ return NULL;
+ }
+
#ifdef DEBUG_CRYPTO
- ssh_print_hexa("mac: ",data,hmac_digest_len(type));
- if (finallen != hmac_digest_len(type)) {
- printf("Final len is %d\n",finallen);
- }
- ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type));
+ ssh_print_hexa("mac: ",data,hmac_digest_len(type));
+ if (finallen != hmac_digest_len(type)) {
+ printf("Final len is %d\n",finallen);
+ }
+ ssh_print_hexa("Packet hmac", session->current_crypto->hmacbuf, hmac_digest_len(type));
#endif
- }
-
+ }
crypto->encrypt(crypto, data, out, len);
-
+ }
memcpy(data, out, len);
explicit_bzero(out, len);
SAFE_FREE(out);
diff --git a/src/wrapper.c b/src/wrapper.c
index 16f93274..69484fff 100644
--- a/src/wrapper.c
+++ b/src/wrapper.c
@@ -47,6 +47,7 @@
#include "libssh/crypto.h"
#include "libssh/wrapper.h"
#include "libssh/pki.h"
+#include "libssh/poly1305.h"
static struct ssh_hmac_struct ssh_hmac_tab[] = {
{ "hmac-sha1", SSH_HMAC_SHA1 },
@@ -54,6 +55,7 @@ static struct ssh_hmac_struct ssh_hmac_tab[] = {
{ "hmac-sha2-384", SSH_HMAC_SHA384 },
{ "hmac-sha2-512", SSH_HMAC_SHA512 },
{ "hmac-md5", SSH_HMAC_MD5 },
+ { "aead-poly1305", SSH_HMAC_AEAD_POLY1305 },
{ NULL, 0}
};
@@ -73,6 +75,8 @@ size_t hmac_digest_len(enum ssh_hmac_e type) {
return SHA512_DIGEST_LEN;
case SSH_HMAC_MD5:
return MD5_DIGEST_LEN;
+ case SSH_HMAC_AEAD_POLY1305:
+ return POLY1305_TAGLEN;
default:
return 0;
}
@@ -124,6 +128,9 @@ void ssh_cipher_clear(struct ssh_cipher_struct *cipher){
if (cipher->cleanup != NULL) {
cipher->cleanup(cipher);
}
+ if (cipher->chacha20_schedule != NULL){
+ SAFE_FREE(cipher->chacha20_schedule);
+ }
}
static void cipher_free(struct ssh_cipher_struct *cipher) {
@@ -247,9 +254,14 @@ static int crypt_set_algorithms2(ssh_session session){
}
i = 0;
- /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
- /* out */
- wanted = session->next_crypto->kex_methods[SSH_MAC_C_S];
+ if (session->next_crypto->out_cipher->aead_encrypt != NULL){
+ /* this cipher has integrated MAC */
+ wanted = "aead-poly1305";
+ } else {
+ /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
+ /* out */
+ wanted = session->next_crypto->kex_methods[SSH_MAC_C_S];
+ }
while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) {
i++;
}
@@ -357,7 +369,7 @@ int crypt_set_algorithms(ssh_session session, enum ssh_des_e des_type) {
#ifdef WITH_SERVER
int crypt_set_algorithms_server(ssh_session session){
- char *method = NULL;
+ const char *method = NULL;
int i = 0;
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
@@ -372,9 +384,17 @@ int crypt_set_algorithms_server(ssh_session session){
*/
/* out */
method = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
- while(ssh_ciphertab[i].name && strcmp(method,ssh_ciphertab[i].name))
- i++;
- if(!ssh_ciphertab[i].name){
+
+ for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
+ int cmp;
+
+ cmp = strcmp(method, ssh_ciphertab[i].name);
+ if (cmp == 0) {
+ break;
+ }
+ }
+
+ if (ssh_ciphertab[i].name == NULL) {
ssh_set_error(session,SSH_FATAL,"crypt_set_algorithms_server : "
"no crypto algorithm function found for %s",method);
return SSH_ERROR;
@@ -387,26 +407,16 @@ int crypt_set_algorithms_server(ssh_session session){
return SSH_ERROR;
}
i=0;
- /* in */
- method = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
- while(ssh_ciphertab[i].name && strcmp(method,ssh_ciphertab[i].name))
- i++;
- if(!ssh_ciphertab[i].name){
- ssh_set_error(session,SSH_FATAL,"Crypt_set_algorithms_server :"
- "no crypto algorithm function found for %s",method);
- return SSH_ERROR;
- }
- SSH_LOG(SSH_LOG_PACKET,"Set input algorithm %s",method);
-
- session->next_crypto->in_cipher = cipher_new(i);
- if (session->next_crypto->in_cipher == NULL) {
- ssh_set_error_oom(session);
- return SSH_ERROR;
+ if (session->next_crypto->out_cipher->aead_encrypt != NULL){
+ /* this cipher has integrated MAC */
+ method = "aead-poly1305";
+ } else {
+ /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
+ /* out */
+ method = session->next_crypto->kex_methods[SSH_MAC_S_C];
}
- i=0;
-
/* HMAC algorithm selection */
- method = session->next_crypto->kex_methods[SSH_MAC_S_C];
+
while (ssh_hmactab[i].name && strcmp(method, ssh_hmactab[i].name)) {
i++;
}
@@ -420,11 +430,43 @@ int crypt_set_algorithms_server(ssh_session session){
SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", method);
session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
+
+ /* in */
+ i=0;
+ method = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
+
+ for (i = 0; ssh_ciphertab[i].name; i++) {
+ int cmp;
+
+ cmp = strcmp(method, ssh_ciphertab[i].name);
+ if (cmp == 0) {
+ break;
+ }
+ }
+
+ if (ssh_ciphertab[i].name == NULL) {
+ ssh_set_error(session,SSH_FATAL,"Crypt_set_algorithms_server :"
+ "no crypto algorithm function found for %s",method);
+ return SSH_ERROR;
+ }
+ SSH_LOG(SSH_LOG_PACKET,"Set input algorithm %s",method);
+
+ session->next_crypto->in_cipher = cipher_new(i);
+ if (session->next_crypto->in_cipher == NULL) {
+ ssh_set_error_oom(session);
+ return SSH_ERROR;
+ }
i=0;
method = session->next_crypto->kex_methods[SSH_MAC_C_S];
- while (ssh_hmactab[i].name && strcmp(method, ssh_hmactab[i].name)) {
- i++;
+
+ for (i = 0; ssh_hmactab[i].name != NULL; i++) {
+ int cmp;
+
+ cmp = strcmp(method, ssh_hmactab[i].name);
+ if (cmp == 0) {
+ break;
+ }
}
if (ssh_hmactab[i].name == NULL) {
--
2.14.1
From 494cf5e8040fe4492c722dcad72b18ed19e8ccb6 Mon Sep 17 00:00:00 2001
From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:54 -0600
Subject: [PATCH 13/27] chacha: packet decryption
Signed-off-by: Aris Adamantiadis <aris@xxxxxxxxxxxx>
---
include/libssh/crypto.h | 4 ++
include/libssh/packet.h | 5 +-
src/chachapoly.c | 76 +++++++++++++++++++++++++++++
src/kex.c | 2 +-
src/packet.c | 110 +++++++++++++++++++++---------------------
src/packet_crypt.c | 125 ++++++++++++++++++++++++++++++++++++------------
src/wrapper.c | 58 ++++++++++++++++------
7 files changed, 276 insertions(+), 104 deletions(-)
diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h
index e6e5b8f6..495a9c4c 100644
--- a/include/libssh/crypto.h
+++ b/include/libssh/crypto.h
@@ -155,6 +155,10 @@ struct ssh_cipher_struct {
unsigned long len);
void (*aead_encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
size_t len, uint8_t *mac, uint64_t seq);
+ int (*aead_decrypt_length)(struct ssh_cipher_struct *cipher, void *in,
+ uint8_t *out, size_t len, uint64_t seq);
+ int (*aead_decrypt)(struct ssh_cipher_struct *cipher, void *complete_packet, uint8_t *out,
+ size_t encrypted_size, uint64_t seq);
void (*cleanup)(struct ssh_cipher_struct *cipher);
};
diff --git a/include/libssh/packet.h b/include/libssh/packet.h
index 3a84eb70..b10308f7 100644
--- a/include/libssh/packet.h
+++ b/include/libssh/packet.h
@@ -78,8 +78,9 @@ void ssh_packet_set_default_callbacks(ssh_session session);
void ssh_packet_process(ssh_session session, uint8_t type);
/* PACKET CRYPT */
-uint32_t ssh_packet_decrypt_len(ssh_session session, char *crypted);
-int ssh_packet_decrypt(ssh_session session, void *packet, unsigned int len);
+uint32_t ssh_packet_decrypt_len(ssh_session session, uint8_t *destination, uint8_t *source);
+int ssh_packet_decrypt(ssh_session session, uint8_t *destination, uint8_t *source,
+ size_t start, size_t encrypted_size);
unsigned char *ssh_packet_encrypt(ssh_session session,
void *packet,
unsigned int len);
diff --git a/src/chachapoly.c b/src/chachapoly.c
index 16032179..f3319b62 100644
--- a/src/chachapoly.c
+++ b/src/chachapoly.c
@@ -109,8 +109,82 @@ static void chacha20_poly1305_aead_encrypt(struct ssh_cipher_struct *cipher,
out_packet->payload,
len - sizeof(uint32_t));
+ /* ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx)); */
/* step 4, compute the MAC */
poly1305_auth(tag, (uint8_t *)out_packet, len, poly1305_ctx);
+ /* ssh_print_hexa("poly1305 src", (uint8_t *)out_packet, len);
+ ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN); */
+}
+
+static int chacha20_poly1305_aead_decrypt_length(
+ struct ssh_cipher_struct *cipher,
+ void *in,
+ uint8_t *out,
+ size_t len,
+ uint64_t seq)
+{
+ struct chacha20_poly1305_keysched *keys = cipher->chacha20_schedule;
+
+ if (len < sizeof(uint32_t)) {
+ return SSH_ERROR;
+ }
+ seq = htonll(seq);
+
+ chacha_ivsetup(&keys->k1, (uint8_t *)&seq, zero_block_counter);
+ chacha_encrypt_bytes(&keys->k1,
+ in,
+ (uint8_t *)out,
+ sizeof(uint32_t));
+ return SSH_OK;
+}
+
+static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher,
+ void *complete_packet,
+ uint8_t *out,
+ size_t encrypted_size,
+ uint64_t seq)
+{
+ uint8_t poly1305_ctx[POLY1305_KEYLEN] = {0};
+ uint8_t tag[POLY1305_TAGLEN] = {0};
+ struct chacha20_poly1305_keysched *keys = cipher->chacha20_schedule;
+ uint8_t *mac = (uint8_t *)complete_packet + sizeof(uint32_t) + encrypted_size;
+ int cmp;
+
+ seq = htonll(seq);
+
+ ZERO_STRUCT(poly1305_ctx);
+ chacha_ivsetup(&keys->k2, (uint8_t *)&seq, zero_block_counter);
+ chacha_encrypt_bytes(&keys->k2,
+ poly1305_ctx,
+ poly1305_ctx,
+ POLY1305_KEYLEN);
+#if 0
+ ssh_print_hexa("poly1305_ctx", poly1305_ctx, sizeof(poly1305_ctx));
+#endif
+
+ poly1305_auth(tag, (uint8_t *)complete_packet, encrypted_size +
+ sizeof(uint32_t), poly1305_ctx);
+#if 0
+ ssh_print_hexa("poly1305 src",
+ (uint8_t*)complete_packet,
+ encrypted_size + 4);
+ ssh_print_hexa("poly1305 tag", tag, POLY1305_TAGLEN);
+ ssh_print_hexa("received tag", mac, POLY1305_TAGLEN);
+#endif
+
+ cmp = memcmp(tag, mac, POLY1305_TAGLEN);
+ if(cmp != 0) {
+ /* mac error */
+ SSH_LOG(SSH_LOG_PACKET,"poly1305 verify error");
+ return SSH_ERROR;
+ }
+ chacha_ivsetup(&keys->k2, (uint8_t *)&seq, payload_block_counter);
+ chacha_encrypt_bytes(&keys->k2,
+ (uint8_t *)complete_packet + sizeof(uint32_t),
+ out,
+ encrypted_size);
+
+ return SSH_OK;
}
const struct ssh_cipher_struct chacha20poly1305_cipher = {
@@ -123,4 +197,6 @@ const struct ssh_cipher_struct chacha20poly1305_cipher = {
.set_encrypt_key = chacha20_set_encrypt_key,
.set_decrypt_key = chacha20_set_encrypt_key,
.aead_encrypt = chacha20_poly1305_aead_encrypt,
+ .aead_decrypt_length = chacha20_poly1305_aead_decrypt_length,
+ .aead_decrypt = chacha20_poly1305_aead_decrypt
};
diff --git a/src/kex.c b/src/kex.c
index 20044c32..00f4e00f 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -120,7 +120,7 @@ static const char *supported_methods[] = {
KEY_EXCHANGE,
HOSTKEYS,
CHACHA20 AES BLOWFISH DES_SUPPORTED,
- AES BLOWFISH DES_SUPPORTED,
+ CHACHA20 AES BLOWFISH DES_SUPPORTED,
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
"hmac-sha2-256,hmac-sha2-512,hmac-sha1",
ZLIB,
diff --git a/src/packet.c b/src/packet.c
index f6fb6bff..7d3c14b1 100644
--- a/src/packet.c
+++ b/src/packet.c
@@ -144,20 +144,26 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
ssh_session session= (ssh_session) user;
unsigned int blocksize = (session->current_crypto ?
session->current_crypto->in_cipher->blocksize : 8);
- unsigned char mac[DIGEST_MAX_LEN] = {0};
- char buffer[16] = {0};
+ unsigned int lenfield_blocksize = (session->current_crypto ?
+ session->current_crypto->in_cipher->lenfield_blocksize : 8);
size_t current_macsize = 0;
- const uint8_t *packet;
+ uint8_t *ptr = NULL;
int to_be_read;
int rc;
- uint32_t len, compsize, payloadsize;
+ uint8_t *cleartext_packet = NULL;
+ uint8_t *packet_second_block = NULL;
+ uint8_t *mac = NULL;
+ size_t packet_remaining;
+ uint32_t packet_len, compsize, payloadsize;
uint8_t padding;
size_t processed = 0; /* number of byte processed from the callback */
if(session->current_crypto != NULL) {
current_macsize = hmac_digest_len(session->current_crypto->in_hmac);
}
-
+ if (lenfield_blocksize == 0) {
+ lenfield_blocksize = blocksize;
+ }
if (data == NULL) {
goto error;
}
@@ -178,7 +184,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
#endif
switch(session->packet_state) {
case PACKET_STATE_INIT:
- if (receivedlen < blocksize) {
+ if (receivedlen < lenfield_blocksize) {
/*
* We didn't receive enough data to read at least one
* block size, give up
@@ -187,7 +193,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
SSH_LOG(SSH_LOG_PACKET,
"Waiting for more data (%zu < %zu)",
receivedlen,
- blocksize);
+ lenfield_blocksize);
#endif
return 0;
}
@@ -206,24 +212,21 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
}
}
- memcpy(buffer, data, blocksize);
- processed += blocksize;
- len = ssh_packet_decrypt_len(session, buffer);
-
- rc = ssh_buffer_add_data(session->in_buffer, buffer, blocksize);
- if (rc < 0) {
+ ptr = ssh_buffer_allocate(session->in_buffer, lenfield_blocksize);
+ if (ptr == NULL) {
goto error;
}
+ processed += lenfield_blocksize;
+ packet_len = ssh_packet_decrypt_len(session, ptr, (uint8_t *)data);
- if (len > MAX_PACKET_LEN) {
+ if (packet_len > MAX_PACKET_LEN) {
ssh_set_error(session,
SSH_FATAL,
"read_packet(): Packet len too high(%u %.4x)",
- len, len);
+ packet_len, packet_len);
goto error;
}
-
- to_be_read = len - blocksize + sizeof(uint32_t);
+ to_be_read = packet_len - lenfield_blocksize + sizeof(uint32_t);
if (to_be_read < 0) {
/* remote sshd sends invalid sizes? */
ssh_set_error(session,
@@ -233,59 +236,52 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
goto error;
}
- /* Saves the status of the current operations */
- session->in_packet.len = len;
+ session->in_packet.len = packet_len;
session->packet_state = PACKET_STATE_SIZEREAD;
FALL_THROUGH;
case PACKET_STATE_SIZEREAD:
- len = session->in_packet.len;
- to_be_read = len - blocksize + sizeof(uint32_t) + current_macsize;
+ packet_len = session->in_packet.len;
+ processed = lenfield_blocksize;
+ to_be_read = packet_len + sizeof(uint32_t) + current_macsize;
/* if to_be_read is zero, the whole packet was blocksize bytes. */
if (to_be_read != 0) {
- if (receivedlen - processed < (unsigned int)to_be_read) {
+ if (receivedlen < (unsigned int)to_be_read) {
/* give up, not enough data in buffer */
- SSH_LOG(SSH_LOG_PACKET,"packet: partial packet (read len) [len=%d]",len);
- return processed;
+ SSH_LOG(SSH_LOG_PACKET,
+ "packet: partial packet (read len) "
+ "[len=%d, receivedlen=%d, to_be_read=%d]",
+ packet_len,
+ (int)receivedlen,
+ to_be_read);
+ return 0;
}
- packet = ((uint8_t*)data) + processed;
-#if 0
- ssh_socket_read(session->socket,
- packet,
- to_be_read - current_macsize);
-#endif
-
- rc = ssh_buffer_add_data(session->in_buffer,
- packet,
- to_be_read - current_macsize);
- if (rc < 0) {
- goto error;
- }
- processed += to_be_read - current_macsize;
+ packet_second_block = (uint8_t*)data + lenfield_blocksize;
+ processed = to_be_read - current_macsize;
}
+ /* remaining encrypted bytes from the packet, MAC not included */
+ packet_remaining =
+ packet_len - (lenfield_blocksize - sizeof(uint32_t));
+ cleartext_packet = ssh_buffer_allocate(session->in_buffer,
+ packet_remaining);
if (session->current_crypto) {
/*
- * Decrypt the rest of the packet (blocksize bytes already
+ * Decrypt the rest of the packet (lenfield_blocksize bytes already
* have been decrypted)
*/
- uint32_t buffer_len = ssh_buffer_get_len(session->in_buffer);
-
- /* The following check avoids decrypting zero bytes */
- if (buffer_len > blocksize) {
- uint8_t *payload = ((uint8_t*)ssh_buffer_get(session->in_buffer) + blocksize);
- uint32_t plen = buffer_len - blocksize;
-
- rc = ssh_packet_decrypt(session, payload, plen);
+ if (packet_remaining > 0) {
+ rc = ssh_packet_decrypt(session,
+ cleartext_packet,
+ (uint8_t *)data,
+ lenfield_blocksize,
+ processed - lenfield_blocksize);
if (rc < 0) {
- ssh_set_error(session, SSH_FATAL, "Decrypt error");
+ ssh_set_error(session, SSH_FATAL, "Decryption error");
goto error;
}
}
-
- /* copy the last part from the incoming buffer */
- packet = ((uint8_t *)data) + processed;
- memcpy(mac, packet, current_macsize);
+ mac = packet_second_block + packet_remaining;
rc = ssh_packet_hmac_verify(session, session->in_buffer, mac, session->current_crypto->in_hmac);
if (rc < 0) {
@@ -293,6 +289,8 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
goto error;
}
processed += current_macsize;
+ } else {
+ memcpy(cleartext_packet, packet_second_block, packet_remaining);
}
/* skip the size field which has been processed before */
@@ -342,7 +340,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
ssh_packet_parse_type(session);
SSH_LOG(SSH_LOG_PACKET,
"packet: read type %hhd [len=%d,padding=%hhd,comp=%d,payload=%d]",
- session->in_packet.type, len, padding, compsize, payloadsize);
+ session->in_packet.type, packet_len, padding, compsize, payloadsize);
/* Execute callbacks */
ssh_packet_process(session, session->in_packet.type);
@@ -353,9 +351,9 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
"Processing %" PRIdS " bytes left in socket buffer",
receivedlen-processed);
- packet = ((uint8_t*)data) + processed;
+ ptr = ((uint8_t*)data) + processed;
- rc = ssh_packet_socket_callback(packet, receivedlen - processed,user);
+ rc = ssh_packet_socket_callback(ptr, receivedlen - processed,user);
processed += rc;
}
@@ -372,7 +370,7 @@ int ssh_packet_socket_callback(const void *data, size_t receivedlen, void *user)
error:
session->session_state= SSH_SESSION_STATE_ERROR;
-
+ SSH_LOG(SSH_LOG_PACKET,"Packet: processed %" PRIdS " bytes", processed);
return processed;
}
diff --git a/src/packet_crypt.c b/src/packet_crypt.c
index 5bcb6d65..fb09a225 100644
--- a/src/packet_crypt.c
+++ b/src/packet_crypt.c
@@ -44,40 +44,97 @@
#include "libssh/crypto.h"
#include "libssh/buffer.h"
-uint32_t ssh_packet_decrypt_len(ssh_session session, char *crypted){
- uint32_t decrypted;
-
- if (session->current_crypto) {
- if (ssh_packet_decrypt(session, crypted,
- session->current_crypto->in_cipher->blocksize) < 0) {
- return 0;
+/** @internal
+ * @brief decrypt the packet length from a raw encrypted packet, and store the first decrypted
+ * blocksize.
+ * @returns native byte-ordered decrypted length of the upcoming packet
+ */
+uint32_t ssh_packet_decrypt_len(ssh_session session,
+ uint8_t *destination,
+ uint8_t *source)
+{
+ uint32_t decrypted;
+ int rc;
+
+ if (session->current_crypto != NULL) {
+ if (session->current_crypto->in_cipher->aead_decrypt_length != NULL) {
+ rc =
+ session->current_crypto->in_cipher->set_decrypt_key(
+ session->current_crypto->in_cipher,
+ session->current_crypto->decryptkey,
+ session->current_crypto->decryptIV);
+ if (rc < 0) {
+ return (uint32_t)-1;
+ }
+ session->current_crypto->in_cipher->aead_decrypt_length(
+ session->current_crypto->in_cipher, source, destination,
+ session->current_crypto->in_cipher->lenfield_blocksize,
+ session->recv_seq);
+ } else {
+ rc = ssh_packet_decrypt(
+ session,
+ destination,
+ source,
+ 0,
+ session->current_crypto->in_cipher->blocksize);
+ if (rc < 0) {
+ return 0;
+ }
+ }
+ } else {
+ memcpy(destination, source, 8);
}
- }
- memcpy(&decrypted,crypted,sizeof(decrypted));
- return ntohl(decrypted);
+ memcpy(&decrypted,destination,sizeof(decrypted));
+
+ return ntohl(decrypted);
}
-int ssh_packet_decrypt(ssh_session session, void *data,uint32_t len) {
- struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher;
- char *out = NULL;
+/** @internal
+ * @brief decrypts the content of an SSH packet.
+ * @param[source] source packet, including the encrypted length field
+ * @param[start] index in the packet that was not decrypted yet.
+ * @param[encrypted_size] size of the encrypted data to be decrypted after start.
+ */
+int ssh_packet_decrypt(ssh_session session,
+ uint8_t *destination,
+ uint8_t *source,
+ size_t start,
+ size_t encrypted_size)
+{
+ struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher;
+ int rc;
+
+ if (encrypted_size <= 0) {
+ return SSH_ERROR;
+ }
- assert(len);
+ if (encrypted_size % session->current_crypto->in_cipher->blocksize != 0) {
+ ssh_set_error(session,
+ SSH_FATAL,
+ "Cryptographic functions must be used on multiple of "
+ "blocksize (received %" PRIdS ")",
+ encrypted_size);
+ return SSH_ERROR;
+ }
- if(len % session->current_crypto->in_cipher->blocksize != 0){
- ssh_set_error(session, SSH_FATAL, "Cryptographic functions must be set on at least one blocksize (received %d)",len);
- return SSH_ERROR;
- }
- out = malloc(len);
- if (out == NULL) {
- return -1;
- }
+ rc = crypto->set_decrypt_key(crypto,
+ session->current_crypto->decryptkey,
+ session->current_crypto->decryptIV);
+ if (rc < 0) {
+ return -1;
+ }
- crypto->decrypt(crypto,data,out,len);
+ if (crypto->aead_decrypt != NULL) {
+ return crypto->aead_decrypt(crypto,
+ source,
+ destination,
+ encrypted_size,
+ session->recv_seq);
+ } else {
+ crypto->decrypt(crypto, source + start, destination, encrypted_size);
+ }
- memcpy(data,out,len);
- explicit_bzero(out, len);
- SAFE_FREE(out);
- return 0;
+ return 0;
}
unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len) {
@@ -159,13 +216,21 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
* @return 0 if hmac and mac are equal, < 0 if not or an error
* occurred.
*/
-int ssh_packet_hmac_verify(ssh_session session, ssh_buffer buffer,
- unsigned char *mac, enum ssh_hmac_e type) {
+int ssh_packet_hmac_verify(ssh_session session,
+ ssh_buffer buffer,
+ uint8_t *mac,
+ enum ssh_hmac_e type)
+{
unsigned char hmacbuf[DIGEST_MAX_LEN] = {0};
HMACCTX ctx;
unsigned int len;
uint32_t seq;
+ /* AEAD type have no mac checking */
+ if (type == SSH_HMAC_AEAD_POLY1305) {
+ return SSH_OK;
+ }
+
ctx = hmac_init(session->current_crypto->decryptMAC, hmac_digest_len(type), type);
if (ctx == NULL) {
return -1;
@@ -188,5 +253,3 @@ int ssh_packet_hmac_verify(ssh_session session, ssh_buffer buffer,
return -1;
}
-
-/* vim: set ts=2 sw=2 et cindent: */
diff --git a/src/wrapper.c b/src/wrapper.c
index 69484fff..77af522d 100644
--- a/src/wrapper.c
+++ b/src/wrapper.c
@@ -231,8 +231,13 @@ static int crypt_set_algorithms2(ssh_session session){
int i = 0;
struct ssh_cipher_struct *ssh_ciphertab=ssh_get_ciphertab();
struct ssh_hmac_struct *ssh_hmactab=ssh_get_hmactab();
+ int cmp;
+
+ /*
+ * We must scan the kex entries to find crypto algorithms and set their
+ * appropriate structure.
+ */
- /* we must scan the kex entries to find crypto algorithms and set their appropriate structure */
/* out */
wanted = session->next_crypto->kex_methods[SSH_CRYPT_C_S];
while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) {
@@ -258,12 +263,20 @@ static int crypt_set_algorithms2(ssh_session session){
/* this cipher has integrated MAC */
wanted = "aead-poly1305";
} else {
- /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
+ /*
+ * We must scan the kex entries to find hmac algorithms and set their
+ * appropriate structure.
+ */
+
/* out */
wanted = session->next_crypto->kex_methods[SSH_MAC_C_S];
}
- while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) {
- i++;
+
+ for (i = 0; ssh_hmactab[i].name != NULL; i++) {
+ cmp = strcmp(wanted, ssh_hmactab[i].name);
+ if (cmp == 0) {
+ break;
+ }
}
if (ssh_hmactab[i].name == NULL) {
@@ -275,12 +288,15 @@ static int crypt_set_algorithms2(ssh_session session){
SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted);
session->next_crypto->out_hmac = ssh_hmactab[i].hmac_type;
- i = 0;
/* in */
wanted = session->next_crypto->kex_methods[SSH_CRYPT_S_C];
- while (ssh_ciphertab[i].name && strcmp(wanted, ssh_ciphertab[i].name)) {
- i++;
+
+ for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
+ cmp = strcmp(wanted, ssh_ciphertab[i].name);
+ if (cmp == 0) {
+ break;
+ }
}
if (ssh_ciphertab[i].name == NULL) {
@@ -296,12 +312,20 @@ static int crypt_set_algorithms2(ssh_session session){
ssh_set_error_oom(session);
return SSH_ERROR;
}
- i = 0;
- /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
- wanted = session->next_crypto->kex_methods[SSH_MAC_S_C];
- while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) {
- i++;
+ if (session->next_crypto->in_cipher->aead_encrypt != NULL){
+ /* this cipher has integrated MAC */
+ wanted = "aead-poly1305";
+ } else {
+ /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
+ wanted = session->next_crypto->kex_methods[SSH_MAC_S_C];
+ }
+
+ for (i = 0; ssh_hmactab[i].name != NULL; i++) {
+ cmp = strcmp(wanted, ssh_hmactab[i].name);
+ if (cmp == 0) {
+ break;
+ }
}
if (ssh_hmactab[i].name == NULL) {
@@ -310,7 +334,7 @@ static int crypt_set_algorithms2(ssh_session session){
wanted);
return SSH_ERROR;
}
- SSH_LOG(SSH_LOG_PACKET, "Set HMAC output algorithm to %s", wanted);
+ SSH_LOG(SSH_LOG_PACKET, "Set HMAC input algorithm to %s", wanted);
session->next_crypto->in_hmac = ssh_hmactab[i].hmac_type;
i = 0;
@@ -458,7 +482,13 @@ int crypt_set_algorithms_server(ssh_session session){
}
i=0;
- method = session->next_crypto->kex_methods[SSH_MAC_C_S];
+ if (session->next_crypto->in_cipher->aead_encrypt != NULL){
+ /* this cipher has integrated MAC */
+ method = "aead-poly1305";
+ } else {
+ /* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
+ method = session->next_crypto->kex_methods[SSH_MAC_C_S];
+ }
for (i = 0; ssh_hmactab[i].name != NULL; i++) {
int cmp;
--
2.14.1
From f8497cf2c28292001b260845aa97b4c2abf885d9 Mon Sep 17 00:00:00 2001
From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:55 -0600
Subject: [PATCH 14/27] libgcrypt: make it compatible with chacha20
Signed-off-by: Aris Adamantiadis <aris@xxxxxxxxxxxx>
---
include/libssh/libgcrypt.h | 1 +
src/dh.c | 1 +
src/libgcrypt.c | 21 +++++++++++++++++++++
3 files changed, 23 insertions(+)
diff --git a/include/libssh/libgcrypt.h b/include/libssh/libgcrypt.h
index ec353910..307920d3 100644
--- a/include/libssh/libgcrypt.h
+++ b/include/libssh/libgcrypt.h
@@ -88,6 +88,7 @@ ssh_string ssh_sexp_extract_mpi(const gcry_sexp_t sexp,
#endif /* HAVE_LIBGCRYPT */
+void libgcrypt_init(void);
struct ssh_cipher_struct *ssh_get_ciphertab(void);
#endif /* LIBGCRYPT_H_ */
diff --git a/src/dh.c b/src/dh.c
index 2bc0a9d6..2b6b3f78 100644
--- a/src/dh.c
+++ b/src/dh.c
@@ -190,6 +190,7 @@ int ssh_crypto_init(void) {
p_group1 = NULL;
return -1;
}
+ libgcrypt_init();
#elif defined HAVE_LIBCRYPTO
p_group1 = bignum_new();
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index d9dd5be6..b695b6bb 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -35,6 +35,8 @@
#ifdef HAVE_LIBGCRYPT
#include <gcrypt.h>
+extern const struct ssh_cipher_struct chacha20poly1305_cipher;
+
struct ssh_mac_ctx_struct {
enum ssh_mac_e mac_type;
gcry_md_hd_t ctx;
@@ -637,6 +639,9 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
.encrypt = des1_1_encrypt,
.decrypt = des1_1_decrypt
},
+ {
+ .name = "chacha20-poly1305@xxxxxxxxxxx"
+ },
{
.name = NULL,
.blocksize = 0,
@@ -650,6 +655,22 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
}
};
+void libgcrypt_init(void)
+{
+ size_t i;
+
+ for (i = 0; ssh_ciphertab[i].name != NULL; i++) {
+ int cmp;
+ cmp = strcmp(ssh_ciphertab[i].name, "chacha20-poly1305@xxxxxxxxxxx");
+ if (cmp == 0) {
+ memcpy(&ssh_ciphertab[i],
+ &chacha20poly1305_cipher,
+ sizeof(struct ssh_cipher_struct));
+ break;
+ }
+ }
+}
+
struct ssh_cipher_struct *ssh_get_ciphertab(void)
{
return ssh_ciphertab;
--
2.14.1
From 40f896e553e81358425d3e127faf9003df49049b Mon Sep 17 00:00:00 2001
From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:56 -0600
Subject: [PATCH 15/27] tests: test for chacha20-poly1305@xxxxxxxxxxx
Signed-off-by: Aris Adamantiadis <aris@xxxxxxxxxxxx>
---
tests/client/torture_algorithms.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/tests/client/torture_algorithms.c b/tests/client/torture_algorithms.c
index 76ea2cef..857ba190 100644
--- a/tests/client/torture_algorithms.c
+++ b/tests/client/torture_algorithms.c
@@ -261,6 +261,10 @@ static void torture_algorithms_blowfish_cbc_hmac_sha2_512(void **state) {
}
#endif
+static void torture_algorithms_chacha20_poly1305(void **state) {
+ test_algorithm(*state, NULL/*kex*/, "chacha20-poly1305@xxxxxxxxxxx", NULL);
+}
+
static void torture_algorithms_zlib(void **state) {
struct torture_state *s = *state;
ssh_session session = s->ssh.session;
@@ -441,6 +445,9 @@ int torture_run_tests(void) {
session_setup,
session_teardown),
#endif
+ cmocka_unit_test_setup_teardown(torture_algorithms_chacha20_poly1305,
+ session_setup,
+ session_teardown),
cmocka_unit_test_setup_teardown(torture_algorithms_zlib,
session_setup,
session_teardown),
--
2.14.1
From 7ae788c0e3b74c14127623e0e623d911ea8e72cd Mon Sep 17 00:00:00 2001
From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:57 -0600
Subject: [PATCH 16/27] tests: packet encryption unit testing
That code is really ugly, but it wasn't meant to be modular at all in the
first place.
Signed-off-by: Aris Adamantiadis <aris@xxxxxxxxxxxx>
---
tests/unittests/CMakeLists.txt | 1 +
tests/unittests/torture_packet.c | 193 +++++++++++++++++++++++++++++++++++++++
2 files changed, 194 insertions(+)
create mode 100644 tests/unittests/torture_packet.c
diff --git a/tests/unittests/CMakeLists.txt b/tests/unittests/CMakeLists.txt
index ee8db1d2..0afe11b4 100644
--- a/tests/unittests/CMakeLists.txt
+++ b/tests/unittests/CMakeLists.txt
@@ -12,6 +12,7 @@ add_cmocka_test(torture_config torture_config.c ${TORTURE_LIBRARY})
add_cmocka_test(torture_options torture_options.c ${TORTURE_LIBRARY})
add_cmocka_test(torture_isipaddr torture_isipaddr.c ${TORTURE_LIBRARY})
add_cmocka_test(torture_knownhosts_parsing torture_knownhosts_parsing.c ${TORTURE_LIBRARY})
+add_cmocka_test(torture_packet torture_packet.c ${TORTURE_LIBRARY})
if (UNIX AND NOT WIN32)
# requires ssh-keygen
add_cmocka_test(torture_keyfiles torture_keyfiles.c ${TORTURE_LIBRARY})
diff --git a/tests/unittests/torture_packet.c b/tests/unittests/torture_packet.c
new file mode 100644
index 00000000..0e7d3f1e
--- /dev/null
+++ b/tests/unittests/torture_packet.c
@@ -0,0 +1,193 @@
+#include "config.h"
+
+#define LIBSSH_STATIC
+
+#include "torture.h"
+#include "libssh/libssh.h"
+#include "libssh/session.h"
+#include "libssh/crypto.h"
+#include "libssh/buffer.h"
+#include "libssh/socket.h"
+#include "libssh/callbacks.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include "socket.c"
+
+uint8_t test_data[]="AThis is test data. Use it to check the validity of packet functions";
+uint8_t key[]="iekaeshoa7ooCie2shai8shahngee3ONsee3xoishooj0ojei6aeChieth1iraPh";
+uint8_t iv[]="eixaxughoomah4ui7Aew3ohxuolaifuu";
+uint8_t mac[]="thook2Jai0ahmahyae7ChuuruoPhee8Y";
+
+static uint8_t *copy_data(uint8_t *data, size_t len){
+ uint8_t *ret = malloc(len);
+ assert_non_null(ret);
+ memcpy(ret, data, len);
+ return ret;
+}
+
+static SSH_PACKET_CALLBACK(copy_packet_data){
+ uint8_t *response = user;
+ size_t len = ssh_buffer_get_len(packet);
+ (void)type;
+ (void)session;
+
+ if(len > 1024){
+ len = 1024;
+ }
+ ssh_buffer_get_data(packet, response, len);
+
+ return 0;
+}
+
+static void torture_packet(const char *cipher,
+ const char *mac_type, size_t payload_len) {
+
+ ssh_session session = ssh_new();
+ int verbosity = torture_libssh_verbosity();
+ struct ssh_crypto_struct *crypto;
+ int rc;
+ int sockets[2];
+ uint8_t buffer[1024];
+ uint8_t response[1024];
+ size_t encrypted_packet_len;
+ ssh_packet_callback callbacks[]={copy_packet_data};
+ struct ssh_packet_callbacks_struct cb = {
+ .start='A',
+ .n_callbacks=1,
+ .callbacks=callbacks,
+ .user=response
+ };
+
+ assert_non_null(session);
+ ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
+ crypto = session->next_crypto;
+
+ rc = socketpair(AF_UNIX, SOCK_STREAM, 0, sockets);
+ assert_int_equal(rc, 0);
+
+ session->version = 2;
+ crypto->kex_methods[SSH_KEX] = strdup("curve25519-sha256@xxxxxxxxxx");
+ crypto->kex_methods[SSH_HOSTKEYS] = strdup("ssh-rsa");
+ crypto->kex_methods[SSH_CRYPT_C_S] = strdup(cipher);
+ crypto->kex_methods[SSH_CRYPT_S_C] = strdup(cipher);
+ crypto->kex_methods[SSH_MAC_C_S] = strdup(mac_type);
+ crypto->kex_methods[SSH_MAC_S_C] = strdup(mac_type);
+ crypto->kex_methods[SSH_COMP_C_S] = strdup("none");
+ crypto->kex_methods[SSH_COMP_S_C] = strdup("none");
+ crypto->kex_methods[SSH_LANG_C_S] = strdup("none");
+ crypto->kex_methods[SSH_LANG_S_C] = strdup("none");
+ rc = crypt_set_algorithms(session, 0);
+ assert_int_equal(rc, SSH_OK);
+ session->current_crypto = session->next_crypto;
+ session->next_crypto = crypto_new();
+ crypto->encryptkey = copy_data(key, sizeof(key));
+ crypto->decryptkey = copy_data(key, sizeof(key));
+ crypto->encryptIV = copy_data(iv, sizeof(iv));
+ crypto->decryptIV = copy_data(iv, sizeof(iv));
+ crypto->encryptMAC = copy_data(mac, sizeof(mac));
+ crypto->decryptMAC = copy_data(mac, sizeof(mac));
+
+ assert_non_null(session->out_buffer);
+ ssh_buffer_add_data(session->out_buffer, test_data, payload_len);
+ session->socket->fd_out = sockets[0];
+ session->socket->fd_in = -2;
+ session->socket->write_wontblock = 1;
+ rc = ssh_packet_send(session);
+ assert_int_equal(rc, SSH_OK);
+
+ rc = recv(sockets[1], buffer, sizeof(buffer), 0);
+ assert_true(rc > 0);
+ encrypted_packet_len = rc;
+ assert_in_range(encrypted_packet_len, payload_len + 4, payload_len + (32 * 3));
+ rc = send(sockets[0], buffer, encrypted_packet_len, 0);
+ assert_int_equal(rc, encrypted_packet_len);
+
+ ssh_packet_set_callbacks(session, &cb);
+ explicit_bzero(response, sizeof(response));
+ rc = ssh_packet_socket_callback(buffer, encrypted_packet_len, session);
+ assert_int_not_equal(rc, SSH_ERROR);
+ if(payload_len > 0){
+ assert_memory_equal(response, test_data+1, payload_len-1);
+ }
+ close(sockets[0]);
+ close(sockets[1]);
+ session->socket->fd_in = SSH_INVALID_SOCKET;
+ session->socket->fd_out = SSH_INVALID_SOCKET;
+ ssh_free(session);
+}
+
+static void torture_packet_aes128_ctr() {
+ int i;
+ for (i=1;i<256;++i){
+ torture_packet("aes128-ctr","hmac-sha1",i);
+ }
+}
+
+static void torture_packet_aes192_ctr(){
+ int i;
+ for (i=1;i<256;++i){
+ torture_packet("aes192-ctr","hmac-sha1",i);
+ }
+}
+
+static void torture_packet_aes256_ctr(){
+ int i;
+ for (i=1;i<256;++i){
+ torture_packet("aes256-ctr","hmac-sha1",i);
+ }
+}
+
+static void torture_packet_aes128_cbc() {
+ int i;
+ for (i=1;i<256;++i){
+ torture_packet("aes128-cbc","hmac-sha1",i);
+ }
+}
+
+static void torture_packet_aes192_cbc(){
+ int i;
+ for (i=1;i<256;++i){
+ torture_packet("aes192-cbc","hmac-sha1",i);
+ }
+}
+
+static void torture_packet_aes256_cbc(){
+ int i;
+ for (i=1;i<256;++i){
+ torture_packet("aes256-cbc","hmac-sha1",i);
+ }
+}
+
+static void torture_packet_3des_cbc(){
+ int i;
+ for (i=1;i<256;++i){
+ torture_packet("3des-cbc","hmac-sha1",i);
+ }
+}
+
+static void torture_packet_chacha20(){
+ int i;
+ for (i=1;i<256;++i){
+ torture_packet("chacha20-poly1305@xxxxxxxxxxx","none",i);
+ }
+}
+
+int torture_run_tests(void) {
+ int rc;
+ struct CMUnitTest tests[] = {
+ cmocka_unit_test(torture_packet_aes128_ctr),
+ cmocka_unit_test(torture_packet_aes192_ctr),
+ cmocka_unit_test(torture_packet_aes256_ctr),
+ cmocka_unit_test(torture_packet_aes128_cbc),
+ cmocka_unit_test(torture_packet_aes192_cbc),
+ cmocka_unit_test(torture_packet_aes256_cbc),
+ cmocka_unit_test(torture_packet_3des_cbc),
+ cmocka_unit_test(torture_packet_chacha20)
+ };
+
+ ssh_init();
+ torture_filter_tests(tests);
+ rc = cmocka_run_group_tests(tests, NULL, NULL);
+ ssh_finalize();
+ return rc;
+}
--
2.14.1
From d12cd0749540f1b01843aec1959c7a3695289041 Mon Sep 17 00:00:00 2001
From: Aris Adamantiadis <aris@xxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:58 -0600
Subject: [PATCH 17/27] tests: send more packets of various sizes
Signed-off-by: Aris Adamantiadis <aris@xxxxxxxxxxxx>
---
tests/client/torture_algorithms.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
diff --git a/tests/client/torture_algorithms.c b/tests/client/torture_algorithms.c
index 857ba190..edeb697d 100644
--- a/tests/client/torture_algorithms.c
+++ b/tests/client/torture_algorithms.c
@@ -26,6 +26,7 @@
#include "torture.h"
#include "libssh/libssh.h"
#include "libssh/priv.h"
+#include "libssh/session.h"
#include <errno.h>
#include <sys/types.h>
@@ -49,7 +50,6 @@ static int session_setup(void **state) {
int verbosity = torture_libssh_verbosity();
struct passwd *pwd;
int rc;
-
pwd = getpwnam("bob");
assert_non_null(pwd);
@@ -80,6 +80,15 @@ static void test_algorithm(ssh_session session,
const char *cipher,
const char *hmac) {
int rc;
+ char data[256];
+ size_t len_to_test[] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 10,
+ 12, 15, 16, 20,
+ 31, 32, 33,
+ 63, 64, 65,
+ 100, 127, 128
+ };
+ unsigned int i;
int verbosity = torture_libssh_verbosity();
ssh_options_set(session, SSH_OPTIONS_LOG_VERBOSITY, &verbosity);
@@ -106,6 +115,14 @@ static void test_algorithm(ssh_session session,
rc = ssh_connect(session);
assert_int_equal(rc, SSH_OK);
+ /* send ignore packets of all sizes */
+ memset(data, 0, sizeof(data));
+ for (i = 0; i < (sizeof(len_to_test) / sizeof(size_t)); i++) {
+ memset(data, 'A', len_to_test[i]);
+ ssh_send_ignore(session, data);
+ ssh_handle_packets(session, 50);
+ }
+
rc = ssh_userauth_none(session, NULL);
if (rc != SSH_OK) {
rc = ssh_get_error_code(session);
--
2.14.1
From 3cf6352e2a3d8e3951b129eb43b2fa1cfb4fc176 Mon Sep 17 00:00:00 2001
From: Alberto Aguirre <albaguirre@xxxxxxxxx>
Date: Wed, 28 Feb 2018 10:25:02 -0600
Subject: [PATCH 18/27] packet_crypt: Avoid setting keys every time
Avoid setting keys on every packet decrypt or encrypt operation.
Signed-off-by: Alberto Aguirre <albaguirre@xxxxxxxxx>
---
src/packet_crypt.c | 13 -------------
1 file changed, 13 deletions(-)
diff --git a/src/packet_crypt.c b/src/packet_crypt.c
index fb09a225..68103afb 100644
--- a/src/packet_crypt.c
+++ b/src/packet_crypt.c
@@ -117,13 +117,6 @@ int ssh_packet_decrypt(ssh_session session,
return SSH_ERROR;
}
- rc = crypto->set_decrypt_key(crypto,
- session->current_crypto->decryptkey,
- session->current_crypto->decryptIV);
- if (rc < 0) {
- return -1;
- }
-
if (crypto->aead_decrypt != NULL) {
return crypto->aead_decrypt(crypto,
source,
@@ -177,12 +170,6 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
hmac_update(ctx,data,len);
hmac_final(ctx,session->current_crypto->hmacbuf,&finallen);
- if (crypto->set_encrypt_key(crypto, session->current_crypto->encryptkey,
- session->current_crypto->encryptIV) < 0) {
- SAFE_FREE(out);
- return NULL;
- }
-
#ifdef DEBUG_CRYPTO
ssh_print_hexa("mac: ",data,hmac_digest_len(type));
if (finallen != hmac_digest_len(type)) {
--
2.14.1
From ae45a112ea0aa87c7b5ebea536c3dc9e5a252482 Mon Sep 17 00:00:00 2001
From: Alberto Aguirre <albaguirre@xxxxxxxxx>
Date: Wed, 28 Feb 2018 10:25:04 -0600
Subject: [PATCH 19/27] torture_packet: Set encryption/decryption keys
Signed-off-by: Alberto Aguirre <albaguirre@xxxxxxxxx>
---
tests/unittests/torture_packet.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/tests/unittests/torture_packet.c b/tests/unittests/torture_packet.c
index 0e7d3f1e..a01ea218 100644
--- a/tests/unittests/torture_packet.c
+++ b/tests/unittests/torture_packet.c
@@ -45,6 +45,8 @@ static void torture_packet(const char *cipher,
ssh_session session = ssh_new();
int verbosity = torture_libssh_verbosity();
struct ssh_crypto_struct *crypto;
+ struct ssh_cipher_struct *in_cipher;
+ struct ssh_cipher_struct *out_cipher;
int rc;
int sockets[2];
uint8_t buffer[1024];
@@ -87,6 +89,18 @@ static void torture_packet(const char *cipher,
crypto->encryptMAC = copy_data(mac, sizeof(mac));
crypto->decryptMAC = copy_data(mac, sizeof(mac));
+ in_cipher = session->current_crypto->in_cipher;
+ rc = in_cipher->set_decrypt_key(in_cipher,
+ session->current_crypto->decryptkey,
+ session->current_crypto->decryptIV);
+ assert_int_equal(rc, SSH_OK);
+
+ out_cipher = session->current_crypto->out_cipher;
+ rc = out_cipher->set_encrypt_key(out_cipher,
+ session->current_crypto->encryptkey,
+ session->current_crypto->encryptIV);
+ assert_int_equal(rc, SSH_OK);
+
assert_non_null(session->out_buffer);
ssh_buffer_add_data(session->out_buffer, test_data, payload_len);
session->socket->fd_out = sockets[0];
--
2.14.1
From 5df1af0945bf2a36259bb4d893531440a1a5e817 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:24:59 -0600
Subject: [PATCH 20/27] pkd: add passes for chacha20-poly1305@xxxxxxxxxxx
cipher
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
tests/pkd/pkd_hello.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/tests/pkd/pkd_hello.c b/tests/pkd/pkd_hello.c
index 951bd7b1..7a429e94 100644
--- a/tests/pkd/pkd_hello.c
+++ b/tests/pkd/pkd_hello.c
@@ -258,6 +258,7 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
#endif
#ifdef HAVE_DSA
+#define CHACHA20 "chacha20-poly1305@xxxxxxxxxxx"
#define PKDTESTS_CIPHER(f, client, ciphercmd) \
/* Ciphers. */ \
f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
@@ -266,24 +267,28 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, rsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_rsa, teardown) \
f(client, rsa_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_rsa, teardown) \
+ f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
f(client, dsa_3des_cbc, ciphercmd("3des-cbc"), setup_dsa, teardown) \
f(client, dsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_dsa, teardown) \
f(client, dsa_aes128_ctr, ciphercmd("aes128-ctr"), setup_dsa, teardown) \
f(client, dsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_dsa, teardown) \
f(client, dsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_dsa, teardown) \
f(client, dsa_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_dsa, teardown) \
+ f(client, dsa_chacha20, ciphercmd(CHACHA20), setup_dsa, teardown) \
f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_521, teardown) \
@@ -316,7 +321,7 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ecdsa_521_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_521, teardown) \
- f(client, ecdsa_521_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_521, teardown)
+ f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
#endif
#ifdef HAVE_DSA
--
2.14.1
From 97f2649c1771e569a96f9057e4956b5fbea5a1f3 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Wed, 28 Feb 2018 10:25:00 -0600
Subject: [PATCH 21/27] pkd: move chacha20-poly1305@xxxxxxxxxxx tests to
OPENSSHONLY section
Dropbear does not currently implement the 'chacha20-poly1305@xxxxxxxxxxx'
cipher, so move it into the OPENSSHONLY suite.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
tests/pkd/pkd_hello.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/tests/pkd/pkd_hello.c b/tests/pkd/pkd_hello.c
index 7a429e94..7c499be1 100644
--- a/tests/pkd/pkd_hello.c
+++ b/tests/pkd/pkd_hello.c
@@ -258,7 +258,6 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
#endif
#ifdef HAVE_DSA
-#define CHACHA20 "chacha20-poly1305@xxxxxxxxxxx"
#define PKDTESTS_CIPHER(f, client, ciphercmd) \
/* Ciphers. */ \
f(client, rsa_3des_cbc, ciphercmd("3des-cbc"), setup_rsa, teardown) \
@@ -267,28 +266,24 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, rsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_rsa, teardown) \
f(client, rsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_rsa, teardown) \
f(client, rsa_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_rsa, teardown) \
- f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
f(client, dsa_3des_cbc, ciphercmd("3des-cbc"), setup_dsa, teardown) \
f(client, dsa_aes128_cbc, ciphercmd("aes128-cbc"), setup_dsa, teardown) \
f(client, dsa_aes128_ctr, ciphercmd("aes128-ctr"), setup_dsa, teardown) \
f(client, dsa_aes256_cbc, ciphercmd("aes256-cbc"), setup_dsa, teardown) \
f(client, dsa_aes256_ctr, ciphercmd("aes256-ctr"), setup_dsa, teardown) \
f(client, dsa_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_dsa, teardown) \
- f(client, dsa_chacha20, ciphercmd(CHACHA20), setup_dsa, teardown) \
f(client, ecdsa_256_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_256, teardown) \
- f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_384, teardown) \
- f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_3des_cbc, ciphercmd("3des-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes128_cbc, ciphercmd("aes128-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_521, teardown) \
@@ -325,16 +320,21 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
#endif
#ifdef HAVE_DSA
+#define CHACHA20 "chacha20-poly1305@xxxxxxxxxxx"
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
/* Ciphers. */ \
f(client, rsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_rsa, teardown) \
f(client, rsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_rsa, teardown) \
+ f(client, rsa_chacha20, ciphercmd(CHACHA20), setup_rsa, teardown) \
f(client, dsa_aes192_cbc, ciphercmd("aes192-cbc"), setup_dsa, teardown) \
f(client, dsa_aes192_ctr, ciphercmd("aes192-ctr"), setup_dsa, teardown) \
+ f(client, dsa_chacha20, ciphercmd(CHACHA20), setup_dsa, teardown) \
f(client, ecdsa_256_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_256, teardown) \
f(client, ecdsa_256_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_256, teardown) \
+ f(client, ecdsa_256_chacha20, ciphercmd(CHACHA20), setup_ecdsa_256, teardown) \
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
+ f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown)
#else
@@ -347,7 +347,8 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
- f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown)
+ f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
+ f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
#endif
#ifdef HAVE_DSA
--
2.14.1
From ff325390c4c1229c8d8076bc5dae84d8683f69e2 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Thu, 10 May 2018 16:46:57 -0400
Subject: [PATCH 22/27] tests: fix torture_packet.c `test_data`
Make the `test_data` larger so that tests do not read beyond
its length. Observed in testing with an `-fsanitize=address`
build locally.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
tests/unittests/torture_packet.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/tests/unittests/torture_packet.c b/tests/unittests/torture_packet.c
index a01ea218..729aaccd 100644
--- a/tests/unittests/torture_packet.c
+++ b/tests/unittests/torture_packet.c
@@ -13,7 +13,10 @@
#include <sys/socket.h>
#include "socket.c"
-uint8_t test_data[]="AThis is test data. Use it to check the validity of packet functions";
+uint8_t test_data[]="AThis is test data. Use it to check the validity of packet functions"
+ "AThis is test data. Use it to check the validity of packet functions"
+ "AThis is test data. Use it to check the validity of packet functions"
+ "AThis is test data. Use it to check the validity of packet functions";
uint8_t key[]="iekaeshoa7ooCie2shai8shahngee3ONsee3xoishooj0ojei6aeChieth1iraPh";
uint8_t iv[]="eixaxughoomah4ui7Aew3ohxuolaifuu";
uint8_t mac[]="thook2Jai0ahmahyae7ChuuruoPhee8Y";
--
2.14.1
From 7d80a39135eb789d1f35929ce496252118167f22 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 8 Jun 2018 17:32:27 -0400
Subject: [PATCH 23/27] packet_crypt: fix unused variable compiler warning
The local `rc` variable here is never set. Fix a warning that is
emitted due to `-Wunused-variable`.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
src/packet_crypt.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/packet_crypt.c b/src/packet_crypt.c
index 68103afb..57be946f 100644
--- a/src/packet_crypt.c
+++ b/src/packet_crypt.c
@@ -102,7 +102,6 @@ int ssh_packet_decrypt(ssh_session session,
size_t encrypted_size)
{
struct ssh_cipher_struct *crypto = session->current_crypto->in_cipher;
- int rc;
if (encrypted_size <= 0) {
return SSH_ERROR;
--
2.14.1
From 4e885fc2b6c3586721176c733f1db42182e81fd9 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Wed, 19 Jul 2017 17:23:16 -0400
Subject: [PATCH 24/27] chacha: use a cipher cleanup callback
With this change there is less code specific to the
chacha20-poly1305 cipher found in src/wrapper.c.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
src/chachapoly.c | 7 ++++++-
src/wrapper.c | 3 ---
2 files changed, 6 insertions(+), 4 deletions(-)
diff --git a/src/chachapoly.c b/src/chachapoly.c
index f3319b62..12600e85 100644
--- a/src/chachapoly.c
+++ b/src/chachapoly.c
@@ -187,6 +187,10 @@ static int chacha20_poly1305_aead_decrypt(struct ssh_cipher_struct *cipher,
return SSH_OK;
}
+static void chacha20_cleanup(struct ssh_cipher_struct *cipher) {
+ SAFE_FREE(cipher->chacha20_schedule);
+}
+
const struct ssh_cipher_struct chacha20poly1305_cipher = {
.name = "chacha20-poly1305@xxxxxxxxxxx",
.blocksize = 8,
@@ -198,5 +202,6 @@ const struct ssh_cipher_struct chacha20poly1305_cipher = {
.set_decrypt_key = chacha20_set_encrypt_key,
.aead_encrypt = chacha20_poly1305_aead_encrypt,
.aead_decrypt_length = chacha20_poly1305_aead_decrypt_length,
- .aead_decrypt = chacha20_poly1305_aead_decrypt
+ .aead_decrypt = chacha20_poly1305_aead_decrypt,
+ .cleanup = chacha20_cleanup
};
diff --git a/src/wrapper.c b/src/wrapper.c
index 77af522d..961c3d05 100644
--- a/src/wrapper.c
+++ b/src/wrapper.c
@@ -128,9 +128,6 @@ void ssh_cipher_clear(struct ssh_cipher_struct *cipher){
if (cipher->cleanup != NULL) {
cipher->cleanup(cipher);
}
- if (cipher->chacha20_schedule != NULL){
- SAFE_FREE(cipher->chacha20_schedule);
- }
}
static void cipher_free(struct ssh_cipher_struct *cipher) {
--
2.14.1
From 8895b9337fa08b3af33909840eb081ff8944fa95 Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 8 Jun 2018 18:32:32 -0400
Subject: [PATCH 25/27] packet_crypt: remove `set_decrypt_key` upon
`ssh_packet_decrypt_len`
In 06b9901e64f1ea2a1141115e5645552034d25850, invocations of `set_decrypt_key`
and `set_encrypt_key` were moved into the `ssh_packet_newkeys` callback, away
from the packet decrypt and encrypt functions.
Remove the extra `set_decrypt_key` for the case that an `aead_decrypt_length`
is not NULL. At this time, only the chacha20-poly1305@xxxxxxxxxxx cipher
is affected by this change.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
src/packet_crypt.c | 8 --------
1 file changed, 8 deletions(-)
diff --git a/src/packet_crypt.c b/src/packet_crypt.c
index 57be946f..b2f075c4 100644
--- a/src/packet_crypt.c
+++ b/src/packet_crypt.c
@@ -58,14 +58,6 @@ uint32_t ssh_packet_decrypt_len(ssh_session session,
if (session->current_crypto != NULL) {
if (session->current_crypto->in_cipher->aead_decrypt_length != NULL) {
- rc =
- session->current_crypto->in_cipher->set_decrypt_key(
- session->current_crypto->in_cipher,
- session->current_crypto->decryptkey,
- session->current_crypto->decryptIV);
- if (rc < 0) {
- return (uint32_t)-1;
- }
session->current_crypto->in_cipher->aead_decrypt_length(
session->current_crypto->in_cipher, source, destination,
session->current_crypto->in_cipher->lenfield_blocksize,
--
2.14.1
From 3ae630aca316b4aa1c9dd8f7ab2b43734ff597dd Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 8 Jun 2018 16:16:49 -0700
Subject: [PATCH 26/27] pkd: fix CHACHA20 test lists
Ensure that the CHACHA20 test entires are only included for OpenSSH.
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
tests/pkd/pkd_hello.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tests/pkd/pkd_hello.c b/tests/pkd/pkd_hello.c
index 7c499be1..c0994f15 100644
--- a/tests/pkd/pkd_hello.c
+++ b/tests/pkd/pkd_hello.c
@@ -316,7 +316,7 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ecdsa_521_aes128_ctr, ciphercmd("aes128-ctr"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_cbc, ciphercmd("aes256-cbc"), setup_ecdsa_521, teardown) \
f(client, ecdsa_521_aes256_ctr, ciphercmd("aes256-ctr"), setup_ecdsa_521, teardown) \
- f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
+ f(client, ecdsa_521_blowfish_cbc, ciphercmd("blowfish-cbc"), setup_ecdsa_521, teardown)
#endif
#ifdef HAVE_DSA
@@ -336,7 +336,8 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_chacha20, ciphercmd(CHACHA20), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
- f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown)
+ f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
+ f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
#else
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
/* Ciphers. */ \
@@ -347,8 +348,7 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
f(client, ecdsa_384_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_384, teardown) \
f(client, ecdsa_384_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_384, teardown) \
f(client, ecdsa_521_aes192_cbc, ciphercmd("aes192-cbc"), setup_ecdsa_521, teardown) \
- f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown) \
- f(client, ecdsa_521_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown)
+ f(client, ecdsa_521_aes192_ctr, ciphercmd("aes192-ctr"), setup_ecdsa_521, teardown)
#endif
#ifdef HAVE_DSA
--
2.14.1
From 0c1681553d74db4906f236d40c3c6faaab4f7e7a Mon Sep 17 00:00:00 2001
From: Jon Simons <jon@xxxxxxxxxxxxx>
Date: Fri, 8 Jun 2018 16:18:06 -0700
Subject: [PATCH 27/27] chacha: fix build for mbedTLS
Fix the build for mbedTLS:
* set HAVE_CHACHA for non-mbedTLS builds
* only compile chachapoly.c when HAVE_CHACHA
* use empty CHACHA20 in src/kex.c unless HAVE_CHACHA
Signed-off-by: Jon Simons <jon@xxxxxxxxxxxxx>
---
ConfigureChecks.cmake | 3 ++-
config.h.cmake | 3 +++
src/CMakeLists.txt | 8 +++++++-
src/kex.c | 4 ++++
4 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/ConfigureChecks.cmake b/ConfigureChecks.cmake
index fd8ff136..3bb4a5e0 100644
--- a/ConfigureChecks.cmake
+++ b/ConfigureChecks.cmake
@@ -138,7 +138,8 @@ endif ()
if (NOT WITH_MBEDTLS)
set(HAVE_DSA 1)
-endif()
+ set(HAVE_CHACHA 1)
+endif (NOT WITH_MBEDTLS)
# FUNCTIONS
diff --git a/config.h.cmake b/config.h.cmake
index 61d20acb..044e6032 100644
--- a/config.h.cmake
+++ b/config.h.cmake
@@ -89,6 +89,9 @@
/* Define to 1 if you have DSA */
#cmakedefine HAVE_DSA 1
+/* Define to 1 if you have chacha20-poly1305 */
+#cmakedefine HAVE_CHACHA 1
+
/*************************** FUNCTIONS ***************************/
/* Define to 1 if you have the `EVP_aes128_ctr' function. */
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 90e44253..4edc59f4 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -122,7 +122,6 @@ set(libssh_SRCS
bignum.c
buffer.c
callbacks.c
- chachapoly.c
channels.c
client.c
config.c
@@ -167,6 +166,13 @@ set(libssh_SRCS
external/sc25519.c
)
+if (NOT WITH_MBEDTLS)
+ set(libssh_SRCS
+ ${libssh_SRCS}
+ chachapoly.c
+ )
+endif (NOT WITH_MBEDTLS)
+
if (WITH_GCRYPT)
set(libssh_SRCS
${libssh_SRCS}
diff --git a/src/kex.c b/src/kex.c
index 00f4e00f..8c51566e 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -95,7 +95,11 @@
#define ECDH ""
#endif
+#ifdef HAVE_CHACHA
#define CHACHA20 "chacha20-poly1305@xxxxxxxxxxx,"
+#else /* HAVE_CHACHA */
+#define CHACHA20
+#endif /* HAVE_CHACHA */
#define KEY_EXCHANGE CURVE25519 ECDH "diffie-hellman-group14-sha1,diffie-hellman-group1-sha1"
#define KEX_METHODS_SIZE 10
--
2.14.1
| Re: Missing signed-off for pkg chacha20 patches | Andreas Schneider <asn@xxxxxxxxxxxxxx> |
| Re: Missing signed-off for pkg chacha20 patches | Andreas Schneider <asn@xxxxxxxxxxxxxx> |
| Re: Missing signed-off for pkg chacha20 patches | Andreas Schneider <asn@xxxxxxxxxxxxxx> |
| Missing signed-off for pkg chacha20 patches | Andreas Schneider <asn@xxxxxxxxxxxxxx> |