Add tests and implementation for Encrypt-then-MAC mode

This adds the OpenSSH HMACs that do encrypt then mac. This is a more
secure mode than the original HMAC. Newer AEAD ciphers like chacha20 and
AES-GCM are already encrypt-then-mac, but this also adds it for older
legacy clients that don't support those ciphers yet.

Signed-off-by: Dirkjan Bussink <d.bussink@gmail.com>
Reviewed-by: Jon Simons <jon@jonsimons.org>
Reviewed-by: Jakub Jelen <jjelen@redhat.com>
This commit is contained in:
Dirkjan Bussink
2019-02-12 08:56:37 +00:00
committed by Andreas Schneider
parent e4c7912b35
commit 4a67c19118
9 changed files with 465 additions and 87 deletions

View File

@@ -28,7 +28,7 @@ extern LIBSSH_THREAD int ssh_log_level;
#define KEXALGORITHMS "ecdh-sha2-nistp521,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512,diffie-hellman-group14-sha1"
#define HOSTKEYALGORITHMS "ssh-ed25519,ecdsa-sha2-nistp521,ssh-rsa"
#define PUBKEYACCEPTEDTYPES "rsa-sha2-512,ssh-rsa,ecdsa-sha2-nistp521"
#define MACS "hmac-sha1,hmac-sha2-256"
#define MACS "hmac-sha1,hmac-sha2-256,hmac-sha2-512,hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha2-512-etm@openssh.com"
#define USER_KNOWN_HOSTS "%d/my_known_hosts"
#define GLOBAL_KNOWN_HOSTS "/etc/ssh/my_ssh_known_hosts"
#define BIND_ADDRESS "::1"

View File

@@ -184,15 +184,15 @@ static void torture_options_set_macs(void **state) {
/* Test multiple known MACs */
rc = ssh_options_set(session,
SSH_OPTIONS_HMAC_S_C,
"hmac-sha1,hmac-sha2-256");
"hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha1,hmac-sha2-256");
assert_true(rc == 0);
assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C],
"hmac-sha1,hmac-sha2-256");
"hmac-sha1-etm@openssh.com,hmac-sha2-256-etm@openssh.com,hmac-sha1,hmac-sha2-256");
/* Test unknown MACs */
rc = ssh_options_set(session, SSH_OPTIONS_HMAC_S_C, "unknown-crap@example.com,hmac-sha1,unknown@example.com");
rc = ssh_options_set(session, SSH_OPTIONS_HMAC_S_C, "unknown-crap@example.com,hmac-sha1-etm@openssh.com,unknown@example.com");
assert_true(rc == 0);
assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C], "hmac-sha1");
assert_string_equal(session->opts.wanted_methods[SSH_MAC_S_C], "hmac-sha1-etm@openssh.com");
/* Test all unknown MACs */
rc = ssh_options_set(session, SSH_OPTIONS_HMAC_S_C, "unknown-crap@example.com");

View File

@@ -137,6 +137,30 @@ torture_packet(const char *cipher, const char *mac_type,
ssh_free(session);
}
static void torture_packet_aes128_ctr_etm(UNUSED_PARAM(void **state))
{
int i;
for (i = 1; i < 256; ++i) {
torture_packet("aes128-ctr", "hmac-sha1-etm@openssh.com", "none", i);
}
}
static void torture_packet_aes192_ctr_etm(UNUSED_PARAM(void **state))
{
int i;
for (i = 1; i < 256; ++i) {
torture_packet("aes192-ctr", "hmac-sha1-etm@openssh.com", "none", i);
}
}
static void torture_packet_aes256_ctr_etm(UNUSED_PARAM(void **state))
{
int i;
for (i = 1; i < 256; ++i) {
torture_packet("aes256-ctr", "hmac-sha1-etm@openssh.com", "none", i);
}
}
static void torture_packet_aes128_ctr(void **state)
{
int i;
@@ -191,6 +215,30 @@ static void torture_packet_aes256_cbc(void **state)
}
}
static void torture_packet_aes128_cbc_etm(UNUSED_PARAM(void **state))
{
int i;
for (i = 1; i < 256; ++i) {
torture_packet("aes128-cbc", "hmac-sha1-etm@openssh.com", "none", i);
}
}
static void torture_packet_aes192_cbc_etm(UNUSED_PARAM(void **state))
{
int i;
for (i = 1; i < 256; ++i) {
torture_packet("aes192-cbc", "hmac-sha1-etm@openssh.com", "none", i);
}
}
static void torture_packet_aes256_cbc_etm(UNUSED_PARAM(void **state))
{
int i;
for (i = 1; i < 256; ++i) {
torture_packet("aes256-cbc", "hmac-sha1-etm@openssh.com", "none", i);
}
}
static void torture_packet_3des_cbc(void **state)
{
int i;
@@ -200,6 +248,14 @@ static void torture_packet_3des_cbc(void **state)
}
}
static void torture_packet_3des_cbc_etm(UNUSED_PARAM(void **state))
{
int i;
for (i = 1; i < 256; ++i) {
torture_packet("3des-cbc", "hmac-sha1-etm@openssh.com", "none", i);
}
}
static void torture_packet_chacha20(void **state)
{
int i;
@@ -251,10 +307,17 @@ int torture_run_tests(void) {
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_ctr_etm),
cmocka_unit_test(torture_packet_aes192_ctr_etm),
cmocka_unit_test(torture_packet_aes256_ctr_etm),
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_aes128_cbc_etm),
cmocka_unit_test(torture_packet_aes192_cbc_etm),
cmocka_unit_test(torture_packet_aes256_cbc_etm),
cmocka_unit_test(torture_packet_3des_cbc),
cmocka_unit_test(torture_packet_3des_cbc_etm),
cmocka_unit_test(torture_packet_chacha20),
cmocka_unit_test(torture_packet_aes128_gcm),
cmocka_unit_test(torture_packet_aes256_gcm),