[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 1/4] chachapoly: refactor cipher structs, add no hmac possibility


From c7cd2cf47a632940f6adfa487b7dd6d9a35c4487 Mon Sep 17 00:00:00 2001
From: Meng Tan <mtan@xxxxxxxxxx>
Date: Mon, 18 Sep 2017 11:34:50 +0200
Subject: [PATCH 1/4] chachapoly: refactor cipher structs, add no hmac
 possibility

Signed-off-by: Meng Tan <mtan@xxxxxxxxxx>
---
 include/libssh/crypto.h          | 18 +++++++---
 include/libssh/wrapper.h         |  1 +
 src/libcrypto.c                  | 75 ++++++++++++++++++++++++++++------------
 src/libgcrypt.c                  | 71 ++++++++++++++++++++++++++-----------
 src/packet_crypt.c               | 19 ++++++++--
 src/pki_container_openssh.c      |  6 ++--
 src/wrapper.c                    | 16 ++++++++-
 tests/unittests/torture_crypto.c |  8 ++---
 8 files changed, 157 insertions(+), 57 deletions(-)

diff --git a/include/libssh/crypto.h b/include/libssh/crypto.h
index cc54b33..0cdf96b 100644
--- a/include/libssh/crypto.h
+++ b/include/libssh/crypto.h
@@ -48,6 +48,12 @@
 
 #define DIGEST_MAX_LEN 64
 
+#define SSH_CRYPT_OK 0
+#define SSH_CRYPT_INVALID_ARGUMENT -1
+#define SSH_CRYPT_INTERNAL_ERROR -2
+#define SSH_CRYPT_MAC_INVALID -3
+#define SSH_CRYPT_MESSAGE_INCOMPLETE -4
+
 enum ssh_key_exchange_e {
   /* diffie-hellman-group1-sha1 */
   SSH_KEX_DH_GROUP1_SHA1=1,
@@ -74,7 +80,8 @@ enum ssh_cipher_e {
     SSH_AES256_CBC,
     SSH_AES128_CTR,
     SSH_AES192_CTR,
-    SSH_AES256_CTR
+    SSH_AES256_CTR,
+    SSH_CHACHAPOLY
 };
 
 struct ssh_crypto_struct {
@@ -136,14 +143,15 @@ struct ssh_cipher_struct {
     const EVP_CIPHER *cipher;
     EVP_CIPHER_CTX *ctx;
 #endif
+    unsigned int authlen; /* length of mac for authenticated ciphers */
     unsigned int keysize; /* bytes of key used. != keylen */
     /* sets the new key for immediate use */
     int (*set_encrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
     int (*set_decrypt_key)(struct ssh_cipher_struct *cipher, void *key, void *IV);
-    void (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
-        unsigned long len);
-    void (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
-        unsigned long len);
+    int (*encrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
+        unsigned long len, unsigned int seqnr);
+    int (*decrypt)(struct ssh_cipher_struct *cipher, void *in, void *out,
+        unsigned long len, unsigned int seqnr);
     void (*cleanup)(struct ssh_cipher_struct *cipher);
 };
 
diff --git a/include/libssh/wrapper.h b/include/libssh/wrapper.h
index cdd72d6..09a9ee9 100644
--- a/include/libssh/wrapper.h
+++ b/include/libssh/wrapper.h
@@ -34,6 +34,7 @@ enum ssh_mac_e {
 };
 
 enum ssh_hmac_e {
+  SSH_NO_HMAC = 0,
   SSH_HMAC_SHA1 = 1,
   SSH_HMAC_SHA256,
   SSH_HMAC_SHA384,
diff --git a/src/libcrypto.c b/src/libcrypto.c
index 59c9956..0c5bf92 100644
--- a/src/libcrypto.c
+++ b/src/libcrypto.c
@@ -472,6 +472,7 @@ static void evp_cipher_init(struct ssh_cipher_struct *cipher) {
         /* ciphers not using EVP */
     case SSH_3DES_CBC_SSH1:
     case SSH_DES_CBC_SSH1:
+    case SSH_CHACHAPOLY:
         SSH_LOG(SSH_LOG_WARNING, "This cipher should not use evp_cipher_init");
         break;
     case SSH_NO_CIPHER:
@@ -516,40 +517,46 @@ static int evp_cipher_set_decrypt_key(struct ssh_cipher_struct *cipher,
 }
 
 /* EVP wrapper function for encrypt/decrypt */
-static void evp_cipher_encrypt(struct ssh_cipher_struct *cipher,
-                        void *in,
-                        void *out,
-                        unsigned long len) {
+static int evp_cipher_encrypt(struct ssh_cipher_struct *cipher,
+                              void *in,
+                              void *out,
+                              unsigned long len,
+                              unsigned int seqnr) {
     int outlen = 0;
     int rc = 0;
+    (void)seqnr;
 
     rc = EVP_EncryptUpdate(cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len);
     if (rc != 1){
         SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate failed");
-        return;
+        return SSH_CRYPT_INTERNAL_ERROR;
     }
     if (outlen != (int)len){
         SSH_LOG(SSH_LOG_WARNING, "EVP_EncryptUpdate: output size %d for %zu in", outlen, len);
-        return;
+        return SSH_CRYPT_INTERNAL_ERROR;
     }
+    return SSH_CRYPT_OK;
 }
 
-static void evp_cipher_decrypt(struct ssh_cipher_struct *cipher,
-                        void *in,
-                        void *out,
-                        unsigned long len) {
+static int evp_cipher_decrypt(struct ssh_cipher_struct *cipher,
+                              void *in,
+                              void *out,
+                              unsigned long len,
+                              unsigned int seqnr) {
     int outlen = 0;
     int rc = 0;
+    (void)seqnr;
 
     rc = EVP_DecryptUpdate(cipher->ctx, (unsigned char *)out, &outlen, (unsigned char *)in, len);
     if (rc != 1){
         SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate failed");
-        return;
+        return SSH_CRYPT_INTERNAL_ERROR;
     }
     if (outlen != (int)len){
         SSH_LOG(SSH_LOG_WARNING, "EVP_DecryptUpdate: output size %d for %zu in", outlen, len);
-        return;
+        return SSH_CRYPT_INTERNAL_ERROR;
     }
+    return SSH_CRYPT_OK;
 }
 
 static void evp_cipher_cleanup(struct ssh_cipher_struct *cipher) {
@@ -588,8 +595,9 @@ static int aes_ctr_set_key(struct ssh_cipher_struct *cipher, void *key,
     return SSH_OK;
 }
 
-static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
-    unsigned long len) {
+static int aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+                           unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   unsigned char tmp_buffer[AES_BLOCK_SIZE];
   unsigned int num=0;
   /* Some things are special with ctr128 :
@@ -603,6 +611,7 @@ static void aes_ctr_encrypt(struct ssh_cipher_struct *cipher, void *in, void *ou
 #else
   AES_ctr128_encrypt(in, out, len, &cipher->aes_key->key, cipher->aes_key->IV, tmp_buffer, &num);
 #endif /* HAVE_OPENSSL_CRYPTO_CTR128_ENCRYPT */
+  return SSH_CRYPT_OK;
 }
 
 static void aes_ctr_cleanup(struct ssh_cipher_struct *cipher){
@@ -644,8 +653,9 @@ static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){
     return SSH_OK;
 }
 
-static void des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
+                          void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
 #ifdef DEBUG_CRYPTO
   ssh_print_hexa("Encrypt IV before", cipher->des3_key->ivs.c, 24);
 #endif
@@ -655,10 +665,12 @@ static void des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
 #ifdef DEBUG_CRYPTO
   ssh_print_hexa("Encrypt IV after", cipher->des3_key->ivs.c, 24);
 #endif
+  return SSH_CRYPT_OK;
 }
 
-static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
+                          void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
 #ifdef DEBUG_CRYPTO
   ssh_print_hexa("Decrypt IV before", cipher->des3_key->ivs.c, 24);
 #endif
@@ -670,6 +682,7 @@ static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
 #ifdef DEBUG_CRYPTO
   ssh_print_hexa("Decrypt IV after", cipher->des3_key->ivs.c, 24);
 #endif
+  return SSH_CRYPT_OK;
 }
 
 static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
@@ -684,14 +697,18 @@ static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
     return SSH_OK;
 }
 
-static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
-                           unsigned long len){
+static int des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+                          unsigned long len, unsigned int seqnr){
+    (void)seqnr;
     DES_ncbc_encrypt(in, out, len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 1);
+    return SSH_CRYPT_OK;
 }
 
-static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
-        unsigned long len){
+static int des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+                          unsigned long len, unsigned int seqnr){
+    (void)seqnr;
     DES_ncbc_encrypt(in,out,len, &cipher->des3_key->keys[0], &cipher->des3_key->ivs.v[0], 0);
+    return SSH_CRYPT_OK;
 }
 
 static void des_cleanup(struct ssh_cipher_struct *cipher){
@@ -709,6 +726,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "blowfish-cbc",
     .blocksize = 8,
     .ciphertype = SSH_BLOWFISH_CBC,
+    .authlen = 0,
     .keysize = 128,
     .set_encrypt_key = evp_cipher_set_encrypt_key,
     .set_decrypt_key = evp_cipher_set_decrypt_key,
@@ -726,6 +744,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes128-ctr",
     .blocksize = 16,
     .ciphertype = SSH_AES128_CTR,
+    .authlen = 0,
     .keysize = 128,
     .set_encrypt_key = evp_cipher_set_encrypt_key,
     .set_decrypt_key = evp_cipher_set_decrypt_key,
@@ -737,6 +756,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes192-ctr",
     .blocksize = 16,
     .ciphertype = SSH_AES192_CTR,
+    .authlen = 0,
     .keysize = 192,
     .set_encrypt_key = evp_cipher_set_encrypt_key,
     .set_decrypt_key = evp_cipher_set_decrypt_key,
@@ -748,6 +768,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes256-ctr",
     .blocksize = 16,
     .ciphertype = SSH_AES256_CTR,
+    .authlen = 0,
     .keysize = 256,
     .set_encrypt_key = evp_cipher_set_encrypt_key,
     .set_decrypt_key = evp_cipher_set_decrypt_key,
@@ -760,6 +781,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes128-ctr",
     .blocksize = 16,
     .ciphertype = SSH_AES128_CTR,
+    .authlen = 0,
     .keysize = 128,
     .set_encrypt_key = aes_ctr_set_key,
     .set_decrypt_key = aes_ctr_set_key,
@@ -771,6 +793,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes192-ctr",
     .blocksize = 16,
     .ciphertype = SSH_AES192_CTR,
+    .authlen = 0,
     .keysize = 192,
     .set_encrypt_key = aes_ctr_set_key,
     .set_decrypt_key = aes_ctr_set_key,
@@ -782,6 +805,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes256-ctr",
     .blocksize = 16,
     .ciphertype = SSH_AES256_CTR,
+    .authlen = 0,
     .keysize = 256,
     .set_encrypt_key = aes_ctr_set_key,
     .set_decrypt_key = aes_ctr_set_key,
@@ -795,6 +819,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes128-cbc",
     .blocksize = 16,
     .ciphertype = SSH_AES128_CBC,
+    .authlen = 0,
     .keysize = 128,
     .set_encrypt_key = evp_cipher_set_encrypt_key,
     .set_decrypt_key = evp_cipher_set_decrypt_key,
@@ -806,6 +831,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes192-cbc",
     .blocksize = 16,
     .ciphertype = SSH_AES192_CBC,
+    .authlen = 0,
     .keysize = 192,
     .set_encrypt_key = evp_cipher_set_encrypt_key,
     .set_decrypt_key = evp_cipher_set_decrypt_key,
@@ -817,6 +843,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "aes256-cbc",
     .blocksize = 16,
     .ciphertype = SSH_AES256_CBC,
+    .authlen = 0,
     .keysize = 256,
     .set_encrypt_key = evp_cipher_set_encrypt_key,
     .set_decrypt_key = evp_cipher_set_decrypt_key,
@@ -830,6 +857,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "3des-cbc",
     .blocksize = 8,
     .ciphertype = SSH_3DES_CBC,
+    .authlen = 0,
     .keysize = 192,
     .set_encrypt_key = evp_cipher_set_encrypt_key,
     .set_decrypt_key = evp_cipher_set_decrypt_key,
@@ -841,6 +869,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "3des-cbc-ssh1",
     .blocksize = 8,
     .ciphertype = SSH_3DES_CBC_SSH1,
+    .authlen = 0,
     .keysize = 192,
     .set_encrypt_key = des3_set_key,
     .set_decrypt_key = des3_set_key,
@@ -852,6 +881,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .name = "des-cbc-ssh1",
     .blocksize = 8,
     .ciphertype = SSH_DES_CBC_SSH1,
+    .authlen = 0,
     .keysize = 64,
     .set_encrypt_key = des1_set_key,
     .set_decrypt_key = des1_set_key,
@@ -872,4 +902,3 @@ struct ssh_cipher_struct *ssh_get_ciphertab(void)
 }
 
 #endif /* LIBCRYPTO */
-
diff --git a/src/libgcrypt.c b/src/libgcrypt.c
index 0e85d5d..22eaa00 100644
--- a/src/libgcrypt.c
+++ b/src/libgcrypt.c
@@ -320,14 +320,18 @@ static int blowfish_set_key(struct ssh_cipher_struct *cipher, void *key, void *I
   return 0;
 }
 
-static void blowfish_encrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int blowfish_encrypt(struct ssh_cipher_struct *cipher, void *in,
+                            void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
-static void blowfish_decrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int blowfish_decrypt(struct ssh_cipher_struct *cipher, void *in,
+                            void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
 static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
@@ -382,14 +386,18 @@ static int aes_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
   return 0;
 }
 
-static void aes_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
-    unsigned long len) {
+static int aes_encrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+                       unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
-static void aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
-    unsigned long len) {
+static int aes_decrypt(struct ssh_cipher_struct *cipher, void *in, void *out,
+                       unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
 static int des1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV){
@@ -438,24 +446,32 @@ static int des3_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
 }
 
 
-static void des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int des1_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
+                          void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
-static void des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int des1_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
+                          void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
-static void des3_encrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int des3_encrypt(struct ssh_cipher_struct *cipher, void *in,
+                        void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
-static void des3_decrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int des3_decrypt(struct ssh_cipher_struct *cipher, void *in,
+                        void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
 static int des3_1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV) {
@@ -509,18 +525,22 @@ static int des3_1_set_key(struct ssh_cipher_struct *cipher, void *key, void *IV)
   return 0;
 }
 
-static void des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int des3_1_encrypt(struct ssh_cipher_struct *cipher, void *in,
+                          void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_encrypt(cipher->key[0], out, len, in, len);
   gcry_cipher_decrypt(cipher->key[1], in, len, out, len);
   gcry_cipher_encrypt(cipher->key[2], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
-static void des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
-    void *out, unsigned long len) {
+static int des3_1_decrypt(struct ssh_cipher_struct *cipher, void *in,
+                          void *out, unsigned long len, unsigned int seqnr) {
+  (void)seqnr;
   gcry_cipher_decrypt(cipher->key[2], out, len, in, len);
   gcry_cipher_encrypt(cipher->key[1], in, len, out, len);
   gcry_cipher_decrypt(cipher->key[0], out, len, in, len);
+  return SSH_CRYPT_OK;
 }
 
 /* the table of supported ciphers */
@@ -530,6 +550,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 8,
     .keylen          = sizeof(gcry_cipher_hd_t),
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 128,
     .set_encrypt_key = blowfish_set_key,
     .set_decrypt_key = blowfish_set_key,
@@ -541,6 +562,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 16,
     .keylen          = sizeof(gcry_cipher_hd_t),
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 128,
     .set_encrypt_key = aes_set_key,
     .set_decrypt_key = aes_set_key,
@@ -552,6 +574,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
       .blocksize       = 16,
       .keylen          = sizeof(gcry_cipher_hd_t),
       .key             = NULL,
+      .authlen         = 0,
       .keysize         = 192,
       .set_encrypt_key = aes_set_key,
       .set_decrypt_key = aes_set_key,
@@ -563,6 +586,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
       .blocksize       = 16,
       .keylen          = sizeof(gcry_cipher_hd_t),
       .key             = NULL,
+      .authlen         = 0,
       .keysize         = 256,
       .set_encrypt_key = aes_set_key,
       .set_decrypt_key = aes_set_key,
@@ -574,6 +598,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 16,
     .keylen          = sizeof(gcry_cipher_hd_t),
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 128,
     .set_encrypt_key = aes_set_key,
     .set_decrypt_key = aes_set_key,
@@ -585,6 +610,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 16,
     .keylen          = sizeof(gcry_cipher_hd_t),
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 192,
     .set_encrypt_key = aes_set_key,
     .set_decrypt_key = aes_set_key,
@@ -596,6 +622,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 16,
     .keylen          = sizeof(gcry_cipher_hd_t),
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 256,
     .set_encrypt_key = aes_set_key,
     .set_decrypt_key = aes_set_key,
@@ -607,6 +634,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 8,
     .keylen          = sizeof(gcry_cipher_hd_t),
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 192,
     .set_encrypt_key = des3_set_key,
     .set_decrypt_key = des3_set_key,
@@ -618,6 +646,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 8,
     .keylen          = sizeof(gcry_cipher_hd_t) * 3,
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 192,
     .set_encrypt_key = des3_1_set_key,
     .set_decrypt_key = des3_1_set_key,
@@ -629,6 +658,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 8,
     .keylen          = sizeof(gcry_cipher_hd_t),
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 64,
     .set_encrypt_key = des1_set_key,
     .set_decrypt_key = des1_set_key,
@@ -640,6 +670,7 @@ static struct ssh_cipher_struct ssh_ciphertab[] = {
     .blocksize       = 0,
     .keylen          = 0,
     .key             = NULL,
+    .authlen         = 0,
     .keysize         = 0,
     .set_encrypt_key = NULL,
     .set_decrypt_key = NULL,
diff --git a/src/packet_crypt.c b/src/packet_crypt.c
index 94fd10e..1ac9185 100644
--- a/src/packet_crypt.c
+++ b/src/packet_crypt.c
@@ -60,6 +60,7 @@ uint32_t ssh_packet_decrypt_len(ssh_session session, char *crypted){
 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;
+  int res = 0;
 
   assert(len);
 
@@ -72,7 +73,15 @@ int ssh_packet_decrypt(ssh_session session, void *data,uint32_t len) {
     return -1;
   }
 
-  crypto->decrypt(crypto,data,out,len);
+  res = crypto->decrypt(crypto,data,out,len,session->recv_seq);
+  if (res != SSH_CRYPT_OK) {
+      ssh_set_error(session, SSH_FATAL, "Decrypt function failed");
+      if (res == SSH_CRYPT_MAC_INVALID) {
+          ssh_set_error(session, SSH_FATAL, "Invalid MAC");
+      }
+      SAFE_FREE(out);
+      return -1;
+  }
 
   memcpy(data,out,len);
   BURN_BUFFER(out, len);
@@ -87,6 +96,7 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
   unsigned int finallen;
   uint32_t seq;
   enum ssh_hmac_e type;
+  int res = 0;
 
   assert(len);
 
@@ -124,7 +134,12 @@ unsigned char *ssh_packet_encrypt(ssh_session session, void *data, uint32_t len)
 #endif
   }
 
-  crypto->encrypt(crypto, data, out, len);
+  res = crypto->encrypt(crypto, data, out, len, session->send_seq);
+  if (res != 0) {
+      ssh_set_error(session, SSH_FATAL, "Encrypt function failed");
+      SAFE_FREE(out);
+      return NULL;
+  }
 
   memcpy(data, out, len);
   BURN_BUFFER(out, len);
diff --git a/src/pki_container_openssh.c b/src/pki_container_openssh.c
index 551a7f0..9e1b619 100644
--- a/src/pki_container_openssh.c
+++ b/src/pki_container_openssh.c
@@ -264,7 +264,8 @@ static int pki_private_key_decrypt(ssh_string blob,
     cipher.decrypt(&cipher,
                    ssh_string_data(blob),
                    ssh_string_data(blob),
-                   ssh_string_len(blob));
+                   ssh_string_len(blob),
+                   0);
     ssh_cipher_clear(&cipher);
     return SSH_OK;
 }
@@ -545,7 +546,8 @@ static int pki_private_key_encrypt(ssh_buffer privkey_buffer,
     cipher.encrypt(&cipher,
                    ssh_buffer_get(privkey_buffer),
                    ssh_buffer_get(privkey_buffer),
-                   ssh_buffer_get_len(privkey_buffer));
+                   ssh_buffer_get_len(privkey_buffer),
+                   0);
     ssh_cipher_clear(&cipher);
     BURN_BUFFER(passphrase_buffer, sizeof(passphrase_buffer));
 
diff --git a/src/wrapper.c b/src/wrapper.c
index 8ee04b4..aa2e7a8 100644
--- a/src/wrapper.c
+++ b/src/wrapper.c
@@ -54,6 +54,8 @@ 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 },
+  { "<implicit>",    SSH_NO_HMAC },
+  { "none",          SSH_NO_HMAC },
   { NULL,            0}
 };
 
@@ -250,6 +252,9 @@ static int crypt_set_algorithms2(ssh_session session){
   /* 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->ciphertype == SSH_CHACHAPOLY) {
+      wanted = "<implicit>";
+  }
   while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) {
     i++;
   }
@@ -288,6 +293,9 @@ static int crypt_set_algorithms2(ssh_session session){
 
   /* 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];
+  if (session->next_crypto->in_cipher->ciphertype == SSH_CHACHAPOLY) {
+      wanted = "<implicit>";
+  }
   while (ssh_hmactab[i].name && strcmp(wanted, ssh_hmactab[i].name)) {
     i++;
   }
@@ -357,7 +365,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();
@@ -407,6 +415,9 @@ int crypt_set_algorithms_server(ssh_session session){
 
     /* HMAC algorithm selection */
     method = session->next_crypto->kex_methods[SSH_MAC_S_C];
+    if (session->next_crypto->out_cipher->ciphertype == SSH_CHACHAPOLY) {
+        method = "<implicit>";
+    }
     while (ssh_hmactab[i].name && strcmp(method, ssh_hmactab[i].name)) {
       i++;
     }
@@ -423,6 +434,9 @@ 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->ciphertype == SSH_CHACHAPOLY) {
+        method = "<implicit>";
+    }
     while (ssh_hmactab[i].name && strcmp(method, ssh_hmactab[i].name)) {
       i++;
     }
diff --git a/tests/unittests/torture_crypto.c b/tests/unittests/torture_crypto.c
index 3bddb37..7a600fe 100644
--- a/tests/unittests/torture_crypto.c
+++ b/tests/unittests/torture_crypto.c
@@ -69,8 +69,8 @@ static void torture_crypto_aes256_cbc(void **state)
     cipher.encrypt(&cipher,
             cleartext,
             output,
-            sizeof(cleartext)
-            );
+            sizeof(cleartext),
+            0);
 
     assert_memory_equal(output, aes256_cbc_encrypted, sizeof(aes256_cbc_encrypted));
     ssh_cipher_clear(&cipher);
@@ -88,8 +88,8 @@ static void torture_crypto_aes256_cbc(void **state)
     cipher.decrypt(&cipher,
             aes256_cbc_encrypted,
             output,
-            sizeof(aes256_cbc_encrypted)
-            );
+            sizeof(aes256_cbc_encrypted),
+            0);
 
     assert_memory_equal(output, cleartext, sizeof(cleartext));
 
-- 
2.1.4


Archive administrator: postmaster@lists.cynapses.org