Updating link to change in openSUSE:Factory/libssh revision 56.0
OBS-URL: https://build.opensuse.org/package/show/devel:libraries:c_c++/libssh?expand=0&rev=8ca19c4d56099ba193815428765f4443
This commit is contained in:
committed by
Git OBS Bridge
parent
61c3b4b14a
commit
62bb40cc74
519
0001-libcrypto-Implement-OpenSSH-compatible-AES-GCM-ciphe.patch
Normal file
519
0001-libcrypto-Implement-OpenSSH-compatible-AES-GCM-ciphe.patch
Normal file
@@ -0,0 +1,519 @@
|
|||||||
|
From 46090facbae8c8292d2775546082ccbd5e56fbd1 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
Date: Mon, 8 Oct 2018 13:24:49 +0200
|
||||||
|
Subject: [PATCH] libcrypto: Implement OpenSSH-compatible AES-GCM ciphers using
|
||||||
|
OpenSSL
|
||||||
|
|
||||||
|
The commit also propares the internals throughout the code base
|
||||||
|
for the inclusion of a new AEAD cipher, because previously, the
|
||||||
|
source code counted only with chacha20-poly1305 cipher, which
|
||||||
|
is very specific in many cases.
|
||||||
|
|
||||||
|
The SSH_HMAC_AEAD_GCM mac algorithm is not actually used, but the name
|
||||||
|
needed to be defined so we can match in the algorithms selection per
|
||||||
|
OpenSSH specification (MACs are ignored in case GCM is select as a cipher [1]).
|
||||||
|
|
||||||
|
If the provided OpenSSL does not provide EVP_aes_128_gcm() function,
|
||||||
|
the AES-GCM ciphers will not be compiled in.
|
||||||
|
|
||||||
|
[1] https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL.chacha20poly1305?annotate=HEAD
|
||||||
|
|
||||||
|
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
---
|
||||||
|
ConfigureChecks.cmake | 4 +
|
||||||
|
config.h.cmake | 3 +
|
||||||
|
include/libssh/crypto.h | 8 +-
|
||||||
|
include/libssh/wrapper.h | 3 +-
|
||||||
|
src/chachapoly.c | 1 +
|
||||||
|
src/kex.c | 9 +-
|
||||||
|
src/libcrypto.c | 247 +++++++++++++++++++++++++++++++++++++++
|
||||||
|
src/packet_crypt.c | 5 +-
|
||||||
|
src/wrapper.c | 27 ++++-
|
||||||
|
9 files changed, 297 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
Index: libssh-0.8.7/ConfigureChecks.cmake
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/ConfigureChecks.cmake
|
||||||
|
+++ libssh-0.8.7/ConfigureChecks.cmake
|
||||||
|
@@ -110,6 +110,10 @@ if (OPENSSL_FOUND)
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
|
+ check_function_exists(EVP_aes_128_gcm HAVE_OPENSSL_EVP_AES_GCM)
|
||||||
|
+
|
||||||
|
+ set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
|
+ set(CMAKE_REQUIRED_LIBRARIES ${OPENSSL_CRYPTO_LIBRARY})
|
||||||
|
check_function_exists(CRYPTO_THREADID_set_callback HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK)
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_INCLUDES ${OPENSSL_INCLUDE_DIR})
|
||||||
|
Index: libssh-0.8.7/config.h.cmake
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/config.h.cmake
|
||||||
|
+++ libssh-0.8.7/config.h.cmake
|
||||||
|
@@ -100,6 +100,9 @@
|
||||||
|
/* Define to 1 if you have the `EVP_aes128_cbc' function. */
|
||||||
|
#cmakedefine HAVE_OPENSSL_EVP_AES_CBC 1
|
||||||
|
|
||||||
|
+/* Define to 1 if you have the `EVP_aes128_gcm' function. */
|
||||||
|
+#cmakedefine HAVE_OPENSSL_EVP_AES_GCM 1
|
||||||
|
+
|
||||||
|
/* Define to 1 if you have the `CRYPTO_THREADID_set_callback' function. */
|
||||||
|
#cmakedefine HAVE_OPENSSL_CRYPTO_THREADID_SET_CALLBACK 1
|
||||||
|
|
||||||
|
Index: libssh-0.8.7/include/libssh/crypto.h
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/include/libssh/crypto.h
|
||||||
|
+++ libssh-0.8.7/include/libssh/crypto.h
|
||||||
|
@@ -48,6 +48,9 @@
|
||||||
|
|
||||||
|
#define DIGEST_MAX_LEN 64
|
||||||
|
|
||||||
|
+#define AES_GCM_TAGLEN 16
|
||||||
|
+#define AES_GCM_IVLEN 12
|
||||||
|
+
|
||||||
|
enum ssh_key_exchange_e {
|
||||||
|
/* diffie-hellman-group1-sha1 */
|
||||||
|
SSH_KEX_DH_GROUP1_SHA1=1,
|
||||||
|
@@ -78,7 +81,10 @@ enum ssh_cipher_e {
|
||||||
|
SSH_AES256_CBC,
|
||||||
|
SSH_AES128_CTR,
|
||||||
|
SSH_AES192_CTR,
|
||||||
|
- SSH_AES256_CTR
|
||||||
|
+ SSH_AES256_CTR,
|
||||||
|
+ SSH_AEAD_AES128_GCM,
|
||||||
|
+ SSH_AEAD_AES256_GCM,
|
||||||
|
+ SSH_AEAD_CHACHA20_POLY1305
|
||||||
|
};
|
||||||
|
|
||||||
|
struct ssh_crypto_struct {
|
||||||
|
Index: libssh-0.8.7/include/libssh/wrapper.h
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/include/libssh/wrapper.h
|
||||||
|
+++ libssh-0.8.7/include/libssh/wrapper.h
|
||||||
|
@@ -46,7 +46,8 @@ enum ssh_hmac_e {
|
||||||
|
SSH_HMAC_SHA256,
|
||||||
|
SSH_HMAC_SHA512,
|
||||||
|
SSH_HMAC_MD5,
|
||||||
|
- SSH_HMAC_AEAD_POLY1305
|
||||||
|
+ SSH_HMAC_AEAD_POLY1305,
|
||||||
|
+ SSH_HMAC_AEAD_GCM
|
||||||
|
};
|
||||||
|
|
||||||
|
enum ssh_des_e {
|
||||||
|
Index: libssh-0.8.7/src/chachapoly.c
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/src/chachapoly.c
|
||||||
|
+++ libssh-0.8.7/src/chachapoly.c
|
||||||
|
@@ -192,6 +192,7 @@ static void chacha20_cleanup(struct ssh_
|
||||||
|
}
|
||||||
|
|
||||||
|
const struct ssh_cipher_struct chacha20poly1305_cipher = {
|
||||||
|
+ .ciphertype = SSH_AEAD_CHACHA20_POLY1305,
|
||||||
|
.name = "chacha20-poly1305@openssh.com",
|
||||||
|
.blocksize = 8,
|
||||||
|
.lenfield_blocksize = 4,
|
||||||
|
Index: libssh-0.8.7/src/kex.c
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/src/kex.c
|
||||||
|
+++ libssh-0.8.7/src/kex.c
|
||||||
|
@@ -61,10 +61,15 @@
|
||||||
|
# endif /* HAVE_OPENSSL_BLOWFISH_H */
|
||||||
|
|
||||||
|
# ifdef HAVE_OPENSSL_AES_H
|
||||||
|
+# ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||||
|
+# define GCM "aes256-gcm@openssh.com,aes128-gcm@openssh.com,"
|
||||||
|
+# else
|
||||||
|
+# define GCM ""
|
||||||
|
+# endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||||
|
# ifdef BROKEN_AES_CTR
|
||||||
|
-# define AES "aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||||
|
+# define AES GCM "aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||||
|
# else /* BROKEN_AES_CTR */
|
||||||
|
-# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||||
|
+# define AES GCM "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||||
|
# endif /* BROKEN_AES_CTR */
|
||||||
|
# else /* HAVE_OPENSSL_AES_H */
|
||||||
|
# define AES ""
|
||||||
|
Index: libssh-0.8.7/src/libcrypto.c
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/src/libcrypto.c
|
||||||
|
+++ libssh-0.8.7/src/libcrypto.c
|
||||||
|
@@ -491,6 +491,19 @@ static void evp_cipher_init(struct ssh_c
|
||||||
|
SSH_LOG(SSH_LOG_WARNING, "This cipher is not available in evp_cipher_init");
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
+#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||||
|
+ case SSH_AEAD_AES128_GCM:
|
||||||
|
+ cipher->cipher = EVP_aes_128_gcm();
|
||||||
|
+ break;
|
||||||
|
+ case SSH_AEAD_AES256_GCM:
|
||||||
|
+ cipher->cipher = EVP_aes_256_gcm();
|
||||||
|
+ break;
|
||||||
|
+#else
|
||||||
|
+ case SSH_AEAD_AES128_GCM:
|
||||||
|
+ case SSH_AEAD_AES256_GCM:
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "This cipher is not available in evp_cipher_init");
|
||||||
|
+ break;
|
||||||
|
+#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||||
|
case SSH_3DES_CBC:
|
||||||
|
cipher->cipher = EVP_des_ede3_cbc();
|
||||||
|
break;
|
||||||
|
@@ -498,6 +511,9 @@ static void evp_cipher_init(struct ssh_c
|
||||||
|
cipher->cipher = EVP_bf_cbc();
|
||||||
|
break;
|
||||||
|
/* ciphers not using EVP */
|
||||||
|
+ case SSH_AEAD_CHACHA20_POLY1305:
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "The ChaCha cipher can not be handled here");
|
||||||
|
+ break;
|
||||||
|
case SSH_NO_CIPHER:
|
||||||
|
SSH_LOG(SSH_LOG_WARNING, "No valid ciphertype found");
|
||||||
|
break;
|
||||||
|
@@ -517,6 +533,22 @@ static int evp_cipher_set_encrypt_key(st
|
||||||
|
SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptInit_ex failed");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||||
|
+ /* For AES-GCM we need to set IV in specific way */
|
||||||
|
+ if (cipher->ciphertype == SSH_AEAD_AES128_GCM ||
|
||||||
|
+ cipher->ciphertype == SSH_AEAD_AES256_GCM) {
|
||||||
|
+ rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||||
|
+ EVP_CTRL_GCM_SET_IV_FIXED,
|
||||||
|
+ -1,
|
||||||
|
+ (u_char *)IV);
|
||||||
|
+ if (rc != 1) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_IV_FIXED failed");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||||
|
+
|
||||||
|
EVP_CIPHER_CTX_set_padding(cipher->ctx, 0);
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
@@ -534,6 +566,22 @@ static int evp_cipher_set_decrypt_key(st
|
||||||
|
SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptInit_ex failed");
|
||||||
|
return SSH_ERROR;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||||
|
+ /* For AES-GCM we need to set IV in specific way */
|
||||||
|
+ if (cipher->ciphertype == SSH_AEAD_AES128_GCM ||
|
||||||
|
+ cipher->ciphertype == SSH_AEAD_AES256_GCM) {
|
||||||
|
+ rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||||
|
+ EVP_CTRL_GCM_SET_IV_FIXED,
|
||||||
|
+ -1,
|
||||||
|
+ (u_char *)IV);
|
||||||
|
+ if (rc != 1) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_IV_FIXED failed");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||||
|
+
|
||||||
|
EVP_CIPHER_CTX_set_padding(cipher->ctx, 0);
|
||||||
|
|
||||||
|
return SSH_OK;
|
||||||
|
@@ -642,6 +690,175 @@ static void aes_ctr_cleanup(struct ssh_c
|
||||||
|
|
||||||
|
#endif /* HAVE_OPENSSL_EVP_AES_CTR */
|
||||||
|
|
||||||
|
+#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||||
|
+static int
|
||||||
|
+evp_cipher_aead_get_length(struct ssh_cipher_struct *cipher,
|
||||||
|
+ void *in,
|
||||||
|
+ uint8_t *out,
|
||||||
|
+ size_t len,
|
||||||
|
+ uint64_t seq)
|
||||||
|
+{
|
||||||
|
+ (void)seq;
|
||||||
|
+
|
||||||
|
+ /* The length is not encrypted: Copy it to the result buffer */
|
||||||
|
+ memcpy(out, in, len);
|
||||||
|
+
|
||||||
|
+ return SSH_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+evp_cipher_aead_encrypt(struct ssh_cipher_struct *cipher,
|
||||||
|
+ void *in,
|
||||||
|
+ void *out,
|
||||||
|
+ size_t len,
|
||||||
|
+ uint8_t *tag,
|
||||||
|
+ uint64_t seq)
|
||||||
|
+{
|
||||||
|
+ size_t authlen, aadlen;
|
||||||
|
+ u_char lastiv[1];
|
||||||
|
+ int outlen = 0;
|
||||||
|
+ int rc;
|
||||||
|
+
|
||||||
|
+ (void) seq;
|
||||||
|
+
|
||||||
|
+ aadlen = cipher->lenfield_blocksize;
|
||||||
|
+ authlen = cipher->tag_size;
|
||||||
|
+
|
||||||
|
+ /* increment IV */
|
||||||
|
+ rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||||
|
+ EVP_CTRL_GCM_IV_GEN,
|
||||||
|
+ 1,
|
||||||
|
+ lastiv);
|
||||||
|
+ if (rc == 0) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_IV_GEN failed");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Pass over the authenticated data (not encrypted) */
|
||||||
|
+ rc = EVP_EncryptUpdate(cipher->ctx,
|
||||||
|
+ NULL,
|
||||||
|
+ &outlen,
|
||||||
|
+ (unsigned char *)in,
|
||||||
|
+ aadlen);
|
||||||
|
+ if (rc == 0 || outlen != aadlen) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "Failed to pass authenticated data");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ memcpy(out, in, aadlen);
|
||||||
|
+
|
||||||
|
+ /* Encrypt the rest of the data */
|
||||||
|
+ rc = EVP_EncryptUpdate(cipher->ctx,
|
||||||
|
+ (unsigned char *)out + aadlen,
|
||||||
|
+ &outlen,
|
||||||
|
+ (unsigned char *)in + aadlen,
|
||||||
|
+ len - aadlen);
|
||||||
|
+ if (rc != 1 || outlen != len - aadlen) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* compute tag */
|
||||||
|
+ rc = EVP_EncryptFinal(cipher->ctx,
|
||||||
|
+ NULL,
|
||||||
|
+ &outlen);
|
||||||
|
+ if (rc < 0) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptFinal failed: Failed to create a tag");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||||
|
+ EVP_CTRL_GCM_GET_TAG,
|
||||||
|
+ authlen,
|
||||||
|
+ (unsigned char *)tag);
|
||||||
|
+ if (rc != 1) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_GET_TAG failed");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+evp_cipher_aead_decrypt(struct ssh_cipher_struct *cipher,
|
||||||
|
+ void *complete_packet,
|
||||||
|
+ uint8_t *out,
|
||||||
|
+ size_t encrypted_size,
|
||||||
|
+ uint64_t seq)
|
||||||
|
+{
|
||||||
|
+ size_t authlen, aadlen;
|
||||||
|
+ u_char lastiv[1];
|
||||||
|
+ int outlen = 0;
|
||||||
|
+ int rc = 0;
|
||||||
|
+
|
||||||
|
+ (void)seq;
|
||||||
|
+
|
||||||
|
+ aadlen = cipher->lenfield_blocksize;
|
||||||
|
+ authlen = cipher->tag_size;
|
||||||
|
+
|
||||||
|
+ /* increment IV */
|
||||||
|
+ rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||||
|
+ EVP_CTRL_GCM_IV_GEN,
|
||||||
|
+ 1,
|
||||||
|
+ lastiv);
|
||||||
|
+ if (rc == 0) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_IV_GEN failed");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* set tag for authentication */
|
||||||
|
+ rc = EVP_CIPHER_CTX_ctrl(cipher->ctx,
|
||||||
|
+ EVP_CTRL_GCM_SET_TAG,
|
||||||
|
+ authlen,
|
||||||
|
+ (unsigned char *)complete_packet + aadlen + encrypted_size);
|
||||||
|
+ if (rc == 0) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_CTRL_GCM_SET_TAG failed");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Pass over the authenticated data (not encrypted) */
|
||||||
|
+ rc = EVP_DecryptUpdate(cipher->ctx,
|
||||||
|
+ NULL,
|
||||||
|
+ &outlen,
|
||||||
|
+ (unsigned char *)complete_packet,
|
||||||
|
+ aadlen);
|
||||||
|
+ if (rc == 0) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "Failed to pass authenticated data");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+ /* Do not copy the length to the target buffer, because it is already processed */
|
||||||
|
+ //memcpy(out, complete_packet, aadlen);
|
||||||
|
+
|
||||||
|
+ /* Decrypt the rest of the data */
|
||||||
|
+ rc = EVP_DecryptUpdate(cipher->ctx,
|
||||||
|
+ (unsigned char *)out,
|
||||||
|
+ &outlen,
|
||||||
|
+ (unsigned char *)complete_packet + aadlen,
|
||||||
|
+ encrypted_size /* already substracted aadlen*/);
|
||||||
|
+ if (rc != 1) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate failed");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (outlen != (int)encrypted_size) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING,
|
||||||
|
+ "EVP_DecryptUpdate: output size %d for %zd in",
|
||||||
|
+ outlen,
|
||||||
|
+ encrypted_size);
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* verify tag */
|
||||||
|
+ rc = EVP_DecryptFinal(cipher->ctx,
|
||||||
|
+ NULL,
|
||||||
|
+ &outlen);
|
||||||
|
+ if (rc < 0) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptFinal failed: Failed authentication");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return SSH_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||||
|
+
|
||||||
|
/*
|
||||||
|
* The table of supported ciphers
|
||||||
|
*/
|
||||||
|
@@ -765,6 +982,36 @@ static struct ssh_cipher_struct ssh_ciph
|
||||||
|
.decrypt = evp_cipher_decrypt,
|
||||||
|
.cleanup = evp_cipher_cleanup
|
||||||
|
},
|
||||||
|
+#ifdef HAVE_OPENSSL_EVP_AES_GCM
|
||||||
|
+ {
|
||||||
|
+ .name = "aes128-gcm@openssh.com",
|
||||||
|
+ .blocksize = AES_BLOCK_SIZE,
|
||||||
|
+ .lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||||
|
+ .ciphertype = SSH_AEAD_AES128_GCM,
|
||||||
|
+ .keysize = 128,
|
||||||
|
+ .tag_size = AES_GCM_TAGLEN,
|
||||||
|
+ .set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||||
|
+ .set_decrypt_key = evp_cipher_set_decrypt_key,
|
||||||
|
+ .aead_encrypt = evp_cipher_aead_encrypt,
|
||||||
|
+ .aead_decrypt_length = evp_cipher_aead_get_length,
|
||||||
|
+ .aead_decrypt = evp_cipher_aead_decrypt,
|
||||||
|
+ .cleanup = evp_cipher_cleanup
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "aes256-gcm@openssh.com",
|
||||||
|
+ .blocksize = AES_BLOCK_SIZE,
|
||||||
|
+ .lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||||
|
+ .ciphertype = SSH_AEAD_AES256_GCM,
|
||||||
|
+ .keysize = 256,
|
||||||
|
+ .tag_size = AES_GCM_TAGLEN,
|
||||||
|
+ .set_encrypt_key = evp_cipher_set_encrypt_key,
|
||||||
|
+ .set_decrypt_key = evp_cipher_set_decrypt_key,
|
||||||
|
+ .aead_encrypt = evp_cipher_aead_encrypt,
|
||||||
|
+ .aead_decrypt_length = evp_cipher_aead_get_length,
|
||||||
|
+ .aead_decrypt = evp_cipher_aead_decrypt,
|
||||||
|
+ .cleanup = evp_cipher_cleanup
|
||||||
|
+ },
|
||||||
|
+#endif /* HAVE_OPENSSL_EVP_AES_GCM */
|
||||||
|
#endif /* HAS_AES */
|
||||||
|
#ifdef HAS_DES
|
||||||
|
{
|
||||||
|
Index: libssh-0.8.7/src/packet_crypt.c
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/src/packet_crypt.c
|
||||||
|
+++ libssh-0.8.7/src/packet_crypt.c
|
||||||
|
@@ -209,8 +209,9 @@ int ssh_packet_hmac_verify(ssh_session s
|
||||||
|
unsigned int len;
|
||||||
|
uint32_t seq;
|
||||||
|
|
||||||
|
- /* AEAD type have no mac checking */
|
||||||
|
- if (type == SSH_HMAC_AEAD_POLY1305) {
|
||||||
|
+ /* AEAD types have no mac checking */
|
||||||
|
+ if (type == SSH_HMAC_AEAD_POLY1305 ||
|
||||||
|
+ type == SSH_HMAC_AEAD_GCM) {
|
||||||
|
return SSH_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
Index: libssh-0.8.7/src/wrapper.c
|
||||||
|
===================================================================
|
||||||
|
--- libssh-0.8.7.orig/src/wrapper.c
|
||||||
|
+++ libssh-0.8.7/src/wrapper.c
|
||||||
|
@@ -55,6 +55,7 @@ static struct ssh_hmac_struct ssh_hmac_t
|
||||||
|
{ "hmac-sha2-512", SSH_HMAC_SHA512 },
|
||||||
|
{ "hmac-md5", SSH_HMAC_MD5 },
|
||||||
|
{ "aead-poly1305", SSH_HMAC_AEAD_POLY1305 },
|
||||||
|
+ { "aead-gcm", SSH_HMAC_AEAD_GCM },
|
||||||
|
{ NULL, 0}
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -74,6 +75,8 @@ size_t hmac_digest_len(enum ssh_hmac_e t
|
||||||
|
return MD5_DIGEST_LEN;
|
||||||
|
case SSH_HMAC_AEAD_POLY1305:
|
||||||
|
return POLY1305_TAGLEN;
|
||||||
|
+ case SSH_HMAC_AEAD_GCM:
|
||||||
|
+ return AES_GCM_TAGLEN;
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
@@ -253,7 +256,11 @@ static int crypt_set_algorithms2(ssh_ses
|
||||||
|
|
||||||
|
if (session->next_crypto->out_cipher->aead_encrypt != NULL){
|
||||||
|
/* this cipher has integrated MAC */
|
||||||
|
- wanted = "aead-poly1305";
|
||||||
|
+ if (session->next_crypto->out_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
||||||
|
+ wanted = "aead-poly1305";
|
||||||
|
+ } else {
|
||||||
|
+ wanted = "aead-gcm";
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
/*
|
||||||
|
* We must scan the kex entries to find hmac algorithms and set their
|
||||||
|
@@ -307,7 +314,11 @@ static int crypt_set_algorithms2(ssh_ses
|
||||||
|
|
||||||
|
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
|
||||||
|
/* this cipher has integrated MAC */
|
||||||
|
- wanted = "aead-poly1305";
|
||||||
|
+ if (session->next_crypto->in_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
||||||
|
+ wanted = "aead-poly1305";
|
||||||
|
+ } else {
|
||||||
|
+ wanted = "aead-gcm";
|
||||||
|
+ }
|
||||||
|
} 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];
|
||||||
|
@@ -395,7 +406,11 @@ int crypt_set_algorithms_server(ssh_sess
|
||||||
|
i=0;
|
||||||
|
if (session->next_crypto->out_cipher->aead_encrypt != NULL){
|
||||||
|
/* this cipher has integrated MAC */
|
||||||
|
- method = "aead-poly1305";
|
||||||
|
+ if (session->next_crypto->out_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
||||||
|
+ method = "aead-poly1305";
|
||||||
|
+ } else {
|
||||||
|
+ method = "aead-gcm";
|
||||||
|
+ }
|
||||||
|
} else {
|
||||||
|
/* we must scan the kex entries to find hmac algorithms and set their appropriate structure */
|
||||||
|
/* out */
|
||||||
|
@@ -446,7 +461,11 @@ int crypt_set_algorithms_server(ssh_sess
|
||||||
|
|
||||||
|
if (session->next_crypto->in_cipher->aead_encrypt != NULL){
|
||||||
|
/* this cipher has integrated MAC */
|
||||||
|
- method = "aead-poly1305";
|
||||||
|
+ if (session->next_crypto->in_cipher->ciphertype == SSH_AEAD_CHACHA20_POLY1305) {
|
||||||
|
+ method = "aead-poly1305";
|
||||||
|
+ } else {
|
||||||
|
+ method = "aead-gcm";
|
||||||
|
+ }
|
||||||
|
} 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];
|
277
0001-libgcrypt-Implement-OpenSSH-compatible-AES-GCM-ciphe.patch
Normal file
277
0001-libgcrypt-Implement-OpenSSH-compatible-AES-GCM-ciphe.patch
Normal file
@@ -0,0 +1,277 @@
|
|||||||
|
From 5790036a2305d5610ac55adb5382ea55d043998f Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
Date: Mon, 1 Oct 2018 14:32:05 +0200
|
||||||
|
Subject: [PATCH] libgcrypt: Implement OpenSSH-compatible AES-GCM ciphers using
|
||||||
|
libgcrypt
|
||||||
|
|
||||||
|
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
---
|
||||||
|
include/libssh/crypto.h | 1 +
|
||||||
|
src/kex.c | 4 +-
|
||||||
|
src/libgcrypt.c | 201 ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
3 files changed, 205 insertions(+), 1 deletion(-)
|
||||||
|
|
||||||
|
diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h
|
||||||
|
index fc375a4f..8777f0c9 100644
|
||||||
|
--- a/include/libssh/crypto.h
|
||||||
|
+++ b/include/libssh/crypto.h
|
||||||
|
@@ -142,6 +142,7 @@ struct ssh_cipher_struct {
|
||||||
|
size_t keylen; /* length of the key structure */
|
||||||
|
#ifdef HAVE_LIBGCRYPT
|
||||||
|
gcry_cipher_hd_t *key;
|
||||||
|
+ unsigned char last_iv[AES_GCM_IVLEN];
|
||||||
|
#elif defined HAVE_LIBCRYPTO
|
||||||
|
struct ssh_3des_key_schedule *des3_key;
|
||||||
|
struct ssh_aes_key_schedule *aes_key;
|
||||||
|
diff --git a/src/kex.c b/src/kex.c
|
||||||
|
index e0fd5680..382d88fb 100644
|
||||||
|
--- a/src/kex.c
|
||||||
|
+++ b/src/kex.c
|
||||||
|
@@ -40,7 +40,9 @@
|
||||||
|
|
||||||
|
#ifdef HAVE_LIBGCRYPT
|
||||||
|
# define BLOWFISH "blowfish-cbc,"
|
||||||
|
-# define AES "aes256-ctr,aes192-ctr,aes128-ctr,aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||||
|
+# define AES "aes256-gcm@openssh.com,aes128-gcm@openssh.com," \
|
||||||
|
+ "aes256-ctr,aes192-ctr,aes128-ctr," \
|
||||||
|
+ "aes256-cbc,aes192-cbc,aes128-cbc,"
|
||||||
|
# define DES "3des-cbc"
|
||||||
|
# define DES_SUPPORTED "3des-cbc"
|
||||||
|
|
||||||
|
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
|
||||||
|
index f004ffe2..7160bb1c 100644
|
||||||
|
--- a/src/libgcrypt.c
|
||||||
|
+++ b/src/libgcrypt.c
|
||||||
|
@@ -353,6 +353,8 @@ static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||||
|
}
|
||||||
|
if(strstr(cipher->name,"-ctr"))
|
||||||
|
mode=GCRY_CIPHER_MODE_CTR;
|
||||||
|
+ if (strstr(cipher->name, "-gcm"))
|
||||||
|
+ mode = GCRY_CIPHER_MODE_GCM;
|
||||||
|
switch (cipher->keysize) {
|
||||||
|
case 128:
|
||||||
|
if (gcry_cipher_open(&cipher->key[0], GCRY_CIPHER_AES128,
|
||||||
|
@@ -386,6 +388,11 @@ static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||||
|
SAFE_FREE(cipher->key);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
+ } else if (mode == GCRY_CIPHER_MODE_GCM) {
|
||||||
|
+ /* Store the IV so we can handle the packet counter increments later
|
||||||
|
+ * The IV is passed to the cipher context later.
|
||||||
|
+ */
|
||||||
|
+ memcpy(cipher->last_iv, IV, AES_GCM_IVLEN);
|
||||||
|
} else {
|
||||||
|
if(gcry_cipher_setctr(cipher->key[0],IV,16)){
|
||||||
|
SAFE_FREE(cipher->key);
|
||||||
|
@@ -407,6 +414,172 @@ static void aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
|
||||||
|
gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+aes_aead_get_length(struct ssh_cipher_struct *cipher,
|
||||||
|
+ void *in,
|
||||||
|
+ uint8_t *out,
|
||||||
|
+ size_t len,
|
||||||
|
+ uint64_t seq)
|
||||||
|
+{
|
||||||
|
+ (void)seq;
|
||||||
|
+
|
||||||
|
+ /* The length is not encrypted: Copy it to the result buffer */
|
||||||
|
+ memcpy(out, in, len);
|
||||||
|
+
|
||||||
|
+ return SSH_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Increment 64b integer in network byte order */
|
||||||
|
+static void
|
||||||
|
+uint64_inc(unsigned char *counter)
|
||||||
|
+{
|
||||||
|
+ int i;
|
||||||
|
+
|
||||||
|
+ for (i = 7; i >= 0; i--) {
|
||||||
|
+ counter[i]++;
|
||||||
|
+ if (counter[i])
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void
|
||||||
|
+aes_gcm_encrypt(struct ssh_cipher_struct *cipher,
|
||||||
|
+ void *in,
|
||||||
|
+ void *out,
|
||||||
|
+ size_t len,
|
||||||
|
+ uint8_t *tag,
|
||||||
|
+ uint64_t seq)
|
||||||
|
+{
|
||||||
|
+ gpg_error_t err;
|
||||||
|
+ size_t aadlen, authlen;
|
||||||
|
+
|
||||||
|
+ (void)seq;
|
||||||
|
+
|
||||||
|
+ aadlen = cipher->lenfield_blocksize;
|
||||||
|
+ authlen = cipher->tag_size;
|
||||||
|
+
|
||||||
|
+ /* increment IV */
|
||||||
|
+ err = gcry_cipher_setiv(cipher->key[0],
|
||||||
|
+ cipher->last_iv,
|
||||||
|
+ AES_GCM_IVLEN);
|
||||||
|
+ /* This actualy does not increment the packet counter for the
|
||||||
|
+ * current encryption operation, but for the next one. The first
|
||||||
|
+ * operation needs to be completed with the derived IV.
|
||||||
|
+ *
|
||||||
|
+ * The IV buffer has the following structure:
|
||||||
|
+ * [ 4B static IV ][ 8B packet counter ][ 4B block counter ]
|
||||||
|
+ */
|
||||||
|
+ uint64_inc(cipher->last_iv + 4);
|
||||||
|
+ if (err) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s",
|
||||||
|
+ gpg_strerror(err));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Pass the authenticated data (packet_length) */
|
||||||
|
+ err = gcry_cipher_authenticate(cipher->key[0], in, aadlen);
|
||||||
|
+ if (err) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_authenticate failed: %s",
|
||||||
|
+ gpg_strerror(err));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+ memcpy(out, in, aadlen);
|
||||||
|
+
|
||||||
|
+ /* Encrypt the rest of the data */
|
||||||
|
+ err = gcry_cipher_encrypt(cipher->key[0],
|
||||||
|
+ (unsigned char *)out + aadlen,
|
||||||
|
+ len - aadlen,
|
||||||
|
+ (unsigned char *)in + aadlen,
|
||||||
|
+ len - aadlen);
|
||||||
|
+ if (err) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_encrypt failed: %s",
|
||||||
|
+ gpg_strerror(err));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Calculate the tag */
|
||||||
|
+ err = gcry_cipher_gettag(cipher->key[0],
|
||||||
|
+ (void *)tag,
|
||||||
|
+ authlen);
|
||||||
|
+ if (err) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_gettag failed: %s",
|
||||||
|
+ gpg_strerror(err));
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static int
|
||||||
|
+aes_gcm_decrypt(struct ssh_cipher_struct *cipher,
|
||||||
|
+ void *complete_packet,
|
||||||
|
+ uint8_t *out,
|
||||||
|
+ size_t encrypted_size,
|
||||||
|
+ uint64_t seq)
|
||||||
|
+{
|
||||||
|
+ gpg_error_t err;
|
||||||
|
+ size_t aadlen, authlen;
|
||||||
|
+
|
||||||
|
+ (void)seq;
|
||||||
|
+
|
||||||
|
+ aadlen = cipher->lenfield_blocksize;
|
||||||
|
+ authlen = cipher->tag_size;
|
||||||
|
+
|
||||||
|
+ /* increment IV */
|
||||||
|
+ err = gcry_cipher_setiv(cipher->key[0],
|
||||||
|
+ cipher->last_iv,
|
||||||
|
+ AES_GCM_IVLEN);
|
||||||
|
+ /* This actualy does not increment the packet counter for the
|
||||||
|
+ * current encryption operation, but for the next one. The first
|
||||||
|
+ * operation needs to be completed with the derived IV.
|
||||||
|
+ *
|
||||||
|
+ * The IV buffer has the following structure:
|
||||||
|
+ * [ 4B static IV ][ 8B packet counter ][ 4B block counter ]
|
||||||
|
+ */
|
||||||
|
+ uint64_inc(cipher->last_iv + 4);
|
||||||
|
+ if (err) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_setiv failed: %s",
|
||||||
|
+ gpg_strerror(err));
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Pass the authenticated data (packet_length) */
|
||||||
|
+ err = gcry_cipher_authenticate(cipher->key[0],
|
||||||
|
+ complete_packet,
|
||||||
|
+ aadlen);
|
||||||
|
+ if (err) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_authenticate failed: %s",
|
||||||
|
+ gpg_strerror(err));
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+ /* Do not copy the length to the target buffer, because it is already processed */
|
||||||
|
+ //memcpy(out, complete_packet, aadlen);
|
||||||
|
+
|
||||||
|
+ /* Encrypt the rest of the data */
|
||||||
|
+ err = gcry_cipher_decrypt(cipher->key[0],
|
||||||
|
+ out,
|
||||||
|
+ encrypted_size,
|
||||||
|
+ (unsigned char *)complete_packet + aadlen,
|
||||||
|
+ encrypted_size);
|
||||||
|
+ if (err) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "gcry_cipher_decrypt failed: %s",
|
||||||
|
+ gpg_strerror(err));
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Check the tag */
|
||||||
|
+ err = gcry_cipher_checktag(cipher->key[0],
|
||||||
|
+ (unsigned char *)complete_packet + aadlen + encrypted_size,
|
||||||
|
+ authlen);
|
||||||
|
+ if (gpg_err_code(err) == GPG_ERR_CHECKSUM) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "The authentication tag does not match");
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ } else if (err != GPG_ERR_NO_ERROR) {
|
||||||
|
+ SSH_LOG(SSH_LOG_WARNING, "General error while decryption: %s",
|
||||||
|
+ gpg_strerror(err));
|
||||||
|
+ return SSH_ERROR;
|
||||||
|
+ }
|
||||||
|
+ return SSH_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
|
||||||
|
if (cipher->key == NULL) {
|
||||||
|
if (alloc_key(cipher) < 0) {
|
||||||
|
@@ -519,6 +692,34 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
|
||||||
|
.encrypt = aes_encrypt,
|
||||||
|
.decrypt = aes_decrypt
|
||||||
|
},
|
||||||
|
+ {
|
||||||
|
+ .name = "aes128-gcm@openssh.com",
|
||||||
|
+ .blocksize = 16,
|
||||||
|
+ .lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||||
|
+ .keylen = sizeof(gcry_cipher_hd_t),
|
||||||
|
+ .key = NULL,
|
||||||
|
+ .keysize = 128,
|
||||||
|
+ .tag_size = AES_GCM_TAGLEN,
|
||||||
|
+ .set_encrypt_key = aes_set_key,
|
||||||
|
+ .set_decrypt_key = aes_set_key,
|
||||||
|
+ .aead_encrypt = aes_gcm_encrypt,
|
||||||
|
+ .aead_decrypt_length = aes_aead_get_length,
|
||||||
|
+ .aead_decrypt = aes_gcm_decrypt,
|
||||||
|
+ },
|
||||||
|
+ {
|
||||||
|
+ .name = "aes256-gcm@openssh.com",
|
||||||
|
+ .blocksize = 16,
|
||||||
|
+ .lenfield_blocksize = 4, /* not encrypted, but authenticated */
|
||||||
|
+ .keylen = sizeof(gcry_cipher_hd_t),
|
||||||
|
+ .key = NULL,
|
||||||
|
+ .keysize = 256,
|
||||||
|
+ .tag_size = AES_GCM_TAGLEN,
|
||||||
|
+ .set_encrypt_key = aes_set_key,
|
||||||
|
+ .set_decrypt_key = aes_set_key,
|
||||||
|
+ .aead_encrypt = aes_gcm_encrypt,
|
||||||
|
+ .aead_decrypt_length = aes_aead_get_length,
|
||||||
|
+ .aead_decrypt = aes_gcm_decrypt,
|
||||||
|
+ },
|
||||||
|
{
|
||||||
|
.name = "3des-cbc",
|
||||||
|
.blocksize = 8,
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
141
0001-tests-Add-aes-gcm-ciphers-tests.patch
Normal file
141
0001-tests-Add-aes-gcm-ciphers-tests.patch
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
From 42bd7cdf6c6e50786155c904821fc62d6d8e5acb Mon Sep 17 00:00:00 2001
|
||||||
|
From: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
Date: Mon, 8 Oct 2018 13:31:12 +0200
|
||||||
|
Subject: [PATCH] tests: Add aes-gcm ciphers tests
|
||||||
|
|
||||||
|
Signed-off-by: Jakub Jelen <jjelen@redhat.com>
|
||||||
|
Reviewed-by: Andreas Schneider <asn@cryptomilk.org>
|
||||||
|
---
|
||||||
|
tests/client/torture_algorithms.c | 20 ++++++++++++++++++++
|
||||||
|
tests/pkd/pkd_hello.c | 29 +++++++++++++++++++++++++++--
|
||||||
|
2 files changed, 47 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/tests/client/torture_algorithms.c b/tests/client/torture_algorithms.c
|
||||||
|
index c216c99b..9bb67410 100644
|
||||||
|
--- a/tests/client/torture_algorithms.c
|
||||||
|
+++ b/tests/client/torture_algorithms.c
|
||||||
|
@@ -240,6 +240,20 @@ static void torture_algorithms_aes256_ctr_hmac_sha2_512(void **state) {
|
||||||
|
test_algorithm(s->ssh.session, NULL/*kex*/, "aes256-ctr", "hmac-sha2-512");
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void torture_algorithms_aes128_gcm(void **state)
|
||||||
|
+{
|
||||||
|
+ struct torture_state *s = *state;
|
||||||
|
+
|
||||||
|
+ test_algorithm(s->ssh.session, NULL/*kex*/, "aes128-gcm@openssh.com", NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void torture_algorithms_aes256_gcm(void **state)
|
||||||
|
+{
|
||||||
|
+ struct torture_state *s = *state;
|
||||||
|
+
|
||||||
|
+ test_algorithm(s->ssh.session, NULL/*kex*/, "aes256-gcm@openssh.com", NULL);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void torture_algorithms_3des_cbc_hmac_sha1(void **state) {
|
||||||
|
struct torture_state *s = *state;
|
||||||
|
|
||||||
|
@@ -464,6 +478,12 @@ int torture_run_tests(void) {
|
||||||
|
cmocka_unit_test_setup_teardown(torture_algorithms_aes256_ctr_hmac_sha2_512,
|
||||||
|
session_setup,
|
||||||
|
session_teardown),
|
||||||
|
+ cmocka_unit_test_setup_teardown(torture_algorithms_aes128_gcm,
|
||||||
|
+ session_setup,
|
||||||
|
+ session_teardown),
|
||||||
|
+ cmocka_unit_test_setup_teardown(torture_algorithms_aes256_gcm,
|
||||||
|
+ session_setup,
|
||||||
|
+ session_teardown),
|
||||||
|
cmocka_unit_test_setup_teardown(torture_algorithms_3des_cbc_hmac_sha1,
|
||||||
|
session_setup,
|
||||||
|
session_teardown),
|
||||||
|
diff --git a/tests/pkd/pkd_hello.c b/tests/pkd/pkd_hello.c
|
||||||
|
index e14316ec..0fa72d04 100644
|
||||||
|
--- a/tests/pkd/pkd_hello.c
|
||||||
|
+++ b/tests/pkd/pkd_hello.c
|
||||||
|
@@ -383,6 +383,8 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CHACHA20 "chacha20-poly1305@openssh.com"
|
||||||
|
+#define AES128_GCM "aes128-gcm@openssh.com"
|
||||||
|
+#define AES256_GCM "aes256-gcm@openssh.com"
|
||||||
|
|
||||||
|
#ifdef HAVE_DSA
|
||||||
|
#define PKDTESTS_CIPHER_OPENSSHONLY(f, client, ciphercmd) \
|
||||||
|
@@ -390,9 +392,13 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||||
|
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, rsa_aes128_gcm, ciphercmd(AES128_GCM), setup_rsa, teardown) \
|
||||||
|
+ f(client, rsa_aes256_gcm, ciphercmd(AES256_GCM), 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, dsa_aes128_gcm, ciphercmd(AES128_GCM), setup_dsa, teardown) \
|
||||||
|
+ f(client, dsa_aes256_gcm, ciphercmd(AES256_GCM), setup_dsa, teardown) \
|
||||||
|
f(client, ed25519_3des_cbc, ciphercmd("3des-cbc"), setup_ed25519, teardown) \
|
||||||
|
f(client, ed25519_aes128_cbc, ciphercmd("aes128-cbc"), setup_ed25519, teardown) \
|
||||||
|
f(client, ed25519_aes128_ctr, ciphercmd("aes128-ctr"), setup_ed25519, teardown) \
|
||||||
|
@@ -401,21 +407,31 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||||
|
f(client, ed25519_aes192_cbc, ciphercmd("aes192-cbc"), setup_ed25519, teardown) \
|
||||||
|
f(client, ed25519_aes192_ctr, ciphercmd("aes192-ctr"), setup_ed25519, teardown) \
|
||||||
|
f(client, ed25519_chacha20, ciphercmd(CHACHA20), setup_ed25519, teardown) \
|
||||||
|
+ f(client, ed25519_aes128_gcm, ciphercmd(AES128_GCM), setup_ed25519, teardown) \
|
||||||
|
+ f(client, ed25519_aes256_gcm, ciphercmd(AES256_GCM), setup_ed25519, 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_256_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_256, teardown) \
|
||||||
|
+ f(client, ecdsa_256_aes256_gcm, ciphercmd(AES256_GCM), 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_384_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_384, teardown) \
|
||||||
|
+ f(client, ecdsa_384_aes256_gcm, ciphercmd(AES256_GCM), 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_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown) \
|
||||||
|
+ f(client, ecdsa_521_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_521, teardown) \
|
||||||
|
+ f(client, ecdsa_521_aes256_gcm, ciphercmd(AES256_GCM), setup_ecdsa_521, teardown)
|
||||||
|
#else
|
||||||
|
#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, rsa_aes128_gcm, ciphercmd(AES128_GCM), setup_rsa, teardown) \
|
||||||
|
+ f(client, rsa_aes256_gcm, ciphercmd(AES256_GCM), setup_rsa, teardown) \
|
||||||
|
f(client, ed25519_3des_cbc, ciphercmd("3des-cbc"), setup_ed25519, teardown) \
|
||||||
|
f(client, ed25519_aes128_cbc, ciphercmd("aes128-cbc"), setup_ed25519, teardown) \
|
||||||
|
f(client, ed25519_aes128_ctr, ciphercmd("aes128-ctr"), setup_ed25519, teardown) \
|
||||||
|
@@ -424,17 +440,26 @@ static int torture_pkd_setup_ecdsa_521(void **state) {
|
||||||
|
f(client, ed25519_aes192_cbc, ciphercmd("aes192-cbc"), setup_ed25519, teardown) \
|
||||||
|
f(client, ed25519_aes192_ctr, ciphercmd("aes192-ctr"), setup_ed25519, teardown) \
|
||||||
|
f(client, ed25519_chacha20, ciphercmd(CHACHA20), setup_ed25519, teardown) \
|
||||||
|
+ f(client, ed25519_aes128_gcm, ciphercmd(AES128_GCM), setup_ed25519, teardown) \
|
||||||
|
+ f(client, ed25519_aes256_gcm, ciphercmd(AES256_GCM), setup_ed25519, 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_256_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_256, teardown) \
|
||||||
|
+ f(client, ecdsa_256_aes256_gcm, ciphercmd(AES256_GCM), 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_384_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_384, teardown) \
|
||||||
|
+ f(client, ecdsa_384_aes256_gcm, ciphercmd(AES256_GCM), 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_chacha20, ciphercmd(CHACHA20), setup_ecdsa_521, teardown) \
|
||||||
|
+ f(client, ecdsa_521_aes128_gcm, ciphercmd(AES128_GCM), setup_ecdsa_521, teardown) \
|
||||||
|
+ f(client, ecdsa_521_aes256_gcm, ciphercmd(AES256_GCM), setup_ecdsa_521, teardown)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+
|
||||||
|
#ifdef HAVE_DSA
|
||||||
|
#define PKDTESTS_MAC(f, client, maccmd) \
|
||||||
|
/* MACs. */ \
|
||||||
|
--
|
||||||
|
2.21.0
|
||||||
|
|
@@ -1,3 +1,11 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu May 23 15:32:07 UTC 2019 - James McDonough <jmcdonough@suse.com>
|
||||||
|
|
||||||
|
- Add support for new AES-GCM encryption types; (bsc#1134193)
|
||||||
|
* Add 0001-libcrypto-Implement-OpenSSH-compatible-AES-GCM-ciphe.patch
|
||||||
|
* Add 0001-libgcrypt-Implement-OpenSSH-compatible-AES-GCM-ciphe.patch
|
||||||
|
* Add 0001-tests-Add-aes-gcm-ciphers-tests.patch
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Feb 28 07:17:52 UTC 2019 - Stephan Kulow <coolo@suse.com>
|
Thu Feb 28 07:17:52 UTC 2019 - Stephan Kulow <coolo@suse.com>
|
||||||
|
|
||||||
|
@@ -36,6 +36,9 @@ Source1: https://www.libssh.org/files/0.8/libssh-%{version}.tar.xz.asc
|
|||||||
Source2: https://cryptomilk.org/gpgkey-8DFF53E18F2ABC8D8F3C92237EE0FC4DCC014E3D.gpg#/libssh.keyring
|
Source2: https://cryptomilk.org/gpgkey-8DFF53E18F2ABC8D8F3C92237EE0FC4DCC014E3D.gpg#/libssh.keyring
|
||||||
Source99: baselibs.conf
|
Source99: baselibs.conf
|
||||||
Patch0: 0001-disable-timeout-test-on-slow-buildsystems.patch
|
Patch0: 0001-disable-timeout-test-on-slow-buildsystems.patch
|
||||||
|
Patch1: 0001-libcrypto-Implement-OpenSSH-compatible-AES-GCM-ciphe.patch
|
||||||
|
Patch2: 0001-libgcrypt-Implement-OpenSSH-compatible-AES-GCM-ciphe.patch
|
||||||
|
Patch3: 0001-tests-Add-aes-gcm-ciphers-tests.patch
|
||||||
# cmake pulls curl, but libssh is a dependency of it, so avoid cycles by using curl-mini
|
# cmake pulls curl, but libssh is a dependency of it, so avoid cycles by using curl-mini
|
||||||
#!BuildRequires: libcurl4-mini
|
#!BuildRequires: libcurl4-mini
|
||||||
BuildRequires: cmake
|
BuildRequires: cmake
|
||||||
|
Reference in New Issue
Block a user