[Chinese-commits] [fqterm] 08/16: Implement ssh_cipher_t for symmetric ciphers in SSH

Boyuan Yang hosiet-guest at moszumanska.debian.org
Sun Dec 18 15:36:26 UTC 2016


This is an automated email from the git hooks/post-receive script.

hosiet-guest pushed a commit to branch master
in repository fqterm.

commit 0a817b9fcb8e7a1bf5c4a910eb0de1a549b5ba9f
Author: Iru Cai <mytbk920423 at gmail.com>
Date:   Sat Nov 5 14:54:10 2016 +0800

    Implement ssh_cipher_t for symmetric ciphers in SSH
    
    * remove FQTermSSHCipher and FQTermSSH3DES, use ssh_cipher_t instead
    * implement EVP ciphers and 3DES-SSH1
---
 src/protocol/CMakeLists.txt                  |   6 +-
 src/protocol/internal/fqterm_ssh1_packet.cpp |  24 ++--
 src/protocol/internal/fqterm_ssh1_packet.h   |   3 +
 src/protocol/internal/fqterm_ssh2_kex.cpp    |   5 +-
 src/protocol/internal/fqterm_ssh2_packet.cpp |  50 ++------
 src/protocol/internal/fqterm_ssh2_packet.h   |  30 ++---
 src/protocol/internal/fqterm_ssh_cipher.h    |  58 ---------
 src/protocol/internal/fqterm_ssh_des.cpp     | 180 ---------------------------
 src/protocol/internal/fqterm_ssh_des.h       |  74 -----------
 src/protocol/internal/fqterm_ssh_packet.cpp  |  73 ++++-------
 src/protocol/internal/fqterm_ssh_packet.h    |  18 ++-
 src/protocol/internal/ssh_3des-ssh1.c        |  82 ++++++++++++
 src/protocol/internal/ssh_cipher.h           |  46 +++++++
 src/protocol/internal/ssh_evp_cipher.c       |  63 ++++++++++
 14 files changed, 275 insertions(+), 437 deletions(-)

diff --git a/src/protocol/CMakeLists.txt b/src/protocol/CMakeLists.txt
index 84fddf4..5803cb5 100644
--- a/src/protocol/CMakeLists.txt
+++ b/src/protocol/CMakeLists.txt
@@ -17,13 +17,14 @@ set(internal_SRCS
   internal/ssh_pubkey_crypto.c
   internal/ssh_diffie-hellman.h
   internal/ssh_diffie-hellman.c
+  internal/ssh_cipher.h
+  internal/ssh_evp_cipher.c
+  internal/ssh_3des-ssh1.c
   internal/crc32.h
   internal/fqterm_serialization.h
   internal/fqterm_ssh_auth.h
   internal/fqterm_ssh_buffer.h
-  internal/fqterm_ssh_cipher.h
   internal/fqterm_ssh_const.h
-  internal/fqterm_ssh_des.h
   internal/fqterm_ssh_hash.h
   internal/fqterm_ssh_kex.h
   internal/fqterm_ssh2_kex.h
@@ -37,7 +38,6 @@ set(internal_SRCS
   internal/crc32.cpp
   internal/fqterm_ssh_auth.cpp
   internal/fqterm_ssh_buffer.cpp
-  internal/fqterm_ssh_des.cpp
   internal/fqterm_ssh_kex.cpp
   internal/fqterm_ssh2_kex.cpp
   internal/fqterm_ssh_mac.cpp
diff --git a/src/protocol/internal/fqterm_ssh1_packet.cpp b/src/protocol/internal/fqterm_ssh1_packet.cpp
index ded7fe4..aab8f92 100644
--- a/src/protocol/internal/fqterm_ssh1_packet.cpp
+++ b/src/protocol/internal/fqterm_ssh1_packet.cpp
@@ -21,7 +21,6 @@
 #include "fqterm_trace.h"
 #include "fqterm_ssh_buffer.h"
 #include "fqterm_ssh1_packet.h"
-#include "fqterm_ssh_des.h"
 
 #include "fqterm_serialization.h"
 #include "crc32.h"
@@ -43,6 +42,11 @@ namespace FQTerm {
 //
 //==============================================================================
 
+	FQTermSSH1PacketSender::FQTermSSH1PacketSender()
+	{
+		cipher = new_3des_ssh1(1);
+	}
+
 void FQTermSSH1PacketSender::makePacket() {
   int len, padding, i;
   u_int32_t rand_val = 0;
@@ -68,14 +72,20 @@ void FQTermSSH1PacketSender::makePacket() {
   output_buffer_->putInt(ssh_crc32(output_buffer_->data() + 4, output_buffer_->len() - 4));
 
   if (is_encrypt_) {
-    cipher_->encrypt(output_buffer_->data() + 4, output_buffer_->data() + 4, output_buffer_->len() - 4);
-  } 
+	  cipher->crypt(cipher, output_buffer_->data() + 4, output_buffer_->data() + 4, output_buffer_->len() - 4);
+  }
 
 }
 
 //==============================================================================
 //FQTermSSH1PacketReceiver
 //==============================================================================
+
+	FQTermSSH1PacketReceiver::FQTermSSH1PacketReceiver()
+	{
+		cipher = new_3des_ssh1(0);
+	}
+
 void FQTermSSH1PacketReceiver::parseData(FQTermSSHBuffer *input) {
   u_int mycrc, gotcrc;
   u_char *buf = NULL;
@@ -116,11 +126,11 @@ void FQTermSSH1PacketReceiver::parseData(FQTermSSHBuffer *input) {
 
     input->getRawData((char*)sourceData, total_len);
     if (is_decrypt_) {
-      cipher_->decrypt(sourceData, targetData, total_len);
+	    cipher->crypt(cipher, sourceData, targetData, total_len);
     } else {
-      memcpy(targetData, sourceData, total_len);
-    } 
-    
+	    memcpy(targetData, sourceData, total_len);
+    }
+
     buffer_->putRawData((char*)targetData, total_len);
 
     // Check the crc32.
diff --git a/src/protocol/internal/fqterm_ssh1_packet.h b/src/protocol/internal/fqterm_ssh1_packet.h
index a535635..8ea66c7 100644
--- a/src/protocol/internal/fqterm_ssh1_packet.h
+++ b/src/protocol/internal/fqterm_ssh1_packet.h
@@ -28,11 +28,14 @@ namespace FQTerm {
 class FQTermSSH1PacketSender: public FQTermSSHPacketSender {
 protected:
   virtual void makePacket();
+public:
+  FQTermSSH1PacketSender();
 };
 
 class FQTermSSH1PacketReceiver: public FQTermSSHPacketReceiver {
 public:
   virtual void parseData(FQTermSSHBuffer *input);
+  FQTermSSH1PacketReceiver();
 };
 
 }  // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh2_kex.cpp b/src/protocol/internal/fqterm_ssh2_kex.cpp
index 137a41e..e2fd784 100644
--- a/src/protocol/internal/fqterm_ssh2_kex.cpp
+++ b/src/protocol/internal/fqterm_ssh2_kex.cpp
@@ -30,6 +30,7 @@
 #include "fqterm_ssh_md5.h"
 #include "fqterm_trace.h"
 #include "ssh_pubkey_crypto.h"
+#include "ssh_cipher.h"
 
 namespace FQTerm {
 
@@ -296,8 +297,8 @@ bool FQTermSSH2Kex::changeKeyAlg() {
     memcpy(session_id_, H_, SHA_DIGEST_LENGTH);
   }
 
-  packet_sender_->setEncryptionType(SSH_CIPHER_3DES);
-  packet_receiver_->setEncryptionType(SSH_CIPHER_3DES);
+  packet_sender_->cipher = new_ssh_cipher_evp(EVP_des_ede3_cbc, 24, 8, 8, 1);
+  packet_receiver_->cipher = new_ssh_cipher_evp(EVP_des_ede3_cbc, 24, 8, 8, 0);
 
   packet_sender_->setMacType(FQTERM_SSH_HMAC_SHA1);
   packet_receiver_->setMacType(FQTERM_SSH_HMAC_SHA1);
diff --git a/src/protocol/internal/fqterm_ssh2_packet.cpp b/src/protocol/internal/fqterm_ssh2_packet.cpp
index d3094d3..aed8b48 100644
--- a/src/protocol/internal/fqterm_ssh2_packet.cpp
+++ b/src/protocol/internal/fqterm_ssh2_packet.cpp
@@ -21,7 +21,6 @@
 #include "fqterm_trace.h"
 #include "fqterm_ssh_buffer.h"
 #include "fqterm_ssh2_packet.h"
-#include "fqterm_ssh_des.h"
 
 #include "fqterm_serialization.h"
 #include "crc32.h"
@@ -52,8 +51,8 @@ void FQTermSSH2PacketSender::makePacket() {
   int non_padding_len = 4 + 1 + buffer_->len();
 
   int padding_block_len = 8;
-  if (is_encrypt_ && cipher_->blockSize() > padding_block_len) {
-    padding_block_len = cipher_->blockSize();
+  if (is_encrypt_ && cipher->blkSize > padding_block_len) {
+    padding_block_len = cipher->blkSize;
   }
 
   int padding_len = padding_block_len - (non_padding_len % padding_block_len);
@@ -128,7 +127,7 @@ void FQTermSSH2PacketSender::makePacket() {
                               << len << " bytes:\n" 
                               << dumpHexString << std::string((const char *)data, len);
 
-    cipher_->encrypt(data, data, len);
+    FQ_VERIFY(cipher->crypt(cipher, data, data, len)==1);
 
     FQ_TRACE("ssh2packet", 9) << "An encrypted packet (without MAC) made:" 
                               << len << " bytes:\n" 
@@ -138,20 +137,6 @@ void FQTermSSH2PacketSender::makePacket() {
   ++sequence_no_;
 }
 
-void FQTermSSH2PacketSender::setEncryptionType(int cipherType) {
-  cipher_type_ = cipherType;
-
-  delete cipher_;
-  cipher_ = NULL;
-
-  switch (cipher_type_) {
-    case SSH_CIPHER_3DES:
-      cipher_ = new FQTermSSH2TripleDESCBC;
-      break;
-  }
-}
-
-
 //==============================================================================
 //FQTermSSH2PacketReceiver
 //==============================================================================
@@ -162,8 +147,8 @@ void FQTermSSH2PacketReceiver::parseData(FQTermSSHBuffer *input) {
   while (input->len() > 0) {
     // 1. Check the ssh packet
     if (input->len() < 16
-        || (is_decrypt_ && input->len() < cipher_->blockSize())
-        || input->len() < last_expected_input_length_ 
+        || (is_decrypt_ && input->len() < cipher->blkSize)
+        || input->len() < last_expected_input_length_
         ) {
       FQ_TRACE("ssh2packet", 3)
           << "Got an incomplete packet. Wait for more data.";
@@ -172,8 +157,8 @@ void FQTermSSH2PacketReceiver::parseData(FQTermSSHBuffer *input) {
 
     if (last_expected_input_length_ == 0) {
       if (is_decrypt_) {
-        // decrypte the first block to get the packet_length field.
-        cipher_->decrypt(input->data(), input->data(), cipher_->blockSize());
+			// decrypte the first block to get the packet_length field.
+			FQ_VERIFY(cipher->crypt(cipher, input->data(), input->data(), cipher->blkSize)==1);
       }
     } else {
       // last_expected_input_length_ != 0
@@ -203,9 +188,9 @@ void FQTermSSH2PacketReceiver::parseData(FQTermSSHBuffer *input) {
     // 2. decrypte data.
     if (is_decrypt_) {
       // decrypte blocks left.
-      unsigned char *tmp = input->data() + cipher_->blockSize();
-      int left_len = expected_input_len - cipher_->blockSize() - mac_->digestSize();
-      cipher_->decrypt(tmp, tmp, left_len);
+      unsigned char *tmp = input->data() + cipher->blkSize;
+      int left_len = expected_input_len - cipher->blkSize - mac_->digestSize();
+      FQ_VERIFY(cipher->crypt(cipher, tmp, tmp, left_len)==1);
     }
 
     // 3. check MAC
@@ -226,7 +211,7 @@ void FQTermSSH2PacketReceiver::parseData(FQTermSSHBuffer *input) {
     packet_len = input->getInt();
 
     std::vector<u_char> data(packet_len);
-    
+
     input->getRawData((char*)&data[0], packet_len);
     if (is_mac_) {
       input->consume(mac_->digestSize());
@@ -251,17 +236,4 @@ void FQTermSSH2PacketReceiver::parseData(FQTermSSHBuffer *input) {
   }
 }
 
-void FQTermSSH2PacketReceiver::setEncryptionType(int cipherType) {
-  cipher_type_ = cipherType;
-
-  delete cipher_;
-  cipher_ = NULL;
-
-  switch (cipher_type_) {
-    case SSH_CIPHER_3DES:
-      cipher_ = new FQTermSSH2TripleDESCBC;
-      break;
-  }
-}
-
 }  // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh2_packet.h b/src/protocol/internal/fqterm_ssh2_packet.h
index c460984..f2e6b0f 100644
--- a/src/protocol/internal/fqterm_ssh2_packet.h
+++ b/src/protocol/internal/fqterm_ssh2_packet.h
@@ -25,25 +25,21 @@
 
 namespace FQTerm {
 
-class FQTermSSH2PacketSender: public FQTermSSHPacketSender {
- protected:
-  virtual void makePacket();
-
- public:
-  virtual void setEncryptionType(int cipherType);
+class FQTermSSH2PacketSender: public FQTermSSHPacketSender
+{
+protected:
+	virtual void makePacket();
 };
 
-class FQTermSSH2PacketReceiver: public FQTermSSHPacketReceiver {
- private:
-  // greater than 0 if last time an incomplete ssh2 packet received.
-  int last_expected_input_length_;
- public:
-  FQTermSSH2PacketReceiver()
-      : last_expected_input_length_(0) {
-  }
-
-  virtual void parseData(FQTermSSHBuffer *input);
-  virtual void setEncryptionType(int cipherType);
+class FQTermSSH2PacketReceiver: public FQTermSSHPacketReceiver
+{
+private:
+	// greater than 0 if last time an incomplete ssh2 packet received.
+	int last_expected_input_length_;
+public:
+FQTermSSH2PacketReceiver() : last_expected_input_length_(0)	{ }
+
+	virtual void parseData(FQTermSSHBuffer *input);
 };
 
 }  // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_cipher.h b/src/protocol/internal/fqterm_ssh_cipher.h
deleted file mode 100644
index 13bc9f3..0000000
--- a/src/protocol/internal/fqterm_ssh_cipher.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/***************************************************************************
- *   fqterm, a terminal emulator for both BBS and *nix.                    *
- *   Copyright (C) 2008 fqterm development group.                          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program 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 General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.               *
- ***************************************************************************/
-
-#ifndef FQTERM_SSH_CIPHER_H
-#define FQTERM_SSH_CIPHER_H
-
-#include <stdlib.h>
-
-#include "fqterm_ssh_types.h"
-#include "fqterm_ssh_const.h"
-
-namespace FQTerm {
-
-class FQTermSSHCipher {
-protected:
-  const char *d_name;
-
-public:
-  FQTermSSHCipher() {
-    d_name = NULL;
-  }
-  
-  virtual ~FQTermSSHCipher(){}
-  
-  const char *name() const {
-    return d_name;
-  }
-
-  virtual int blockSize() const = 0;
-  virtual int getKeySize() const = 0;
-  virtual int getIVSize() const = 0;
-  
-  virtual void setIV(const u_char *data) = 0;
-  virtual void setKey(const u_char *data) = 0;
-  virtual void encrypt(const u_char *source, u_char *dest, int len) = 0;
-  virtual void decrypt(const u_char *source, u_char *dest, int len) = 0;
-};
-
-}  // namespace FQTerm
-
-#endif  // FQTERM_SSH_CIPHER_H
diff --git a/src/protocol/internal/fqterm_ssh_des.cpp b/src/protocol/internal/fqterm_ssh_des.cpp
deleted file mode 100644
index ca6de16..0000000
--- a/src/protocol/internal/fqterm_ssh_des.cpp
+++ /dev/null
@@ -1,180 +0,0 @@
-/***************************************************************************
- *   fqterm, a terminal emulator for both BBS and *nix.                    *
- *   Copyright (C) 2008 fqterm development group.                          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program 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 General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.               *
- ***************************************************************************/
-
-#include <memory.h>
-#include <openssl/des.h>
-#include <openssl/objects.h>
-#include <openssl/evp.h>
-
-#include "fqterm_ssh_const.h"
-#include "fqterm_ssh_des.h"
-#include "fqterm_trace.h"
-
-namespace FQTerm {
-
-#define DES_ENCRYPT 1
-#define DES_DECRYPT 0
-
-//==============================================================================
-//FQTermSSH1DES3
-//==============================================================================
-
-FQTermSSH1DES3::FQTermSSH1DES3() {
-  d_name = "des3-cbc";
-
-  memset(d_IV1, 0, sizeof(d_IV1));
-  memset(d_IV2, 0, sizeof(d_IV2));
-  memset(d_IV3, 0, sizeof(d_IV3));
-}
-
-int FQTermSSH1DES3::blockSize() const {
-  return 8;
-}
-
-void FQTermSSH1DES3::decrypt(const u_char *source, u_char *dest, int len) {
-  DES_ncbc_encrypt(source, dest, len, &d_key3, &d_IV3, DES_DECRYPT);
-  DES_ncbc_encrypt(dest, dest, len, &d_key2, &d_IV2, DES_ENCRYPT);
-  DES_ncbc_encrypt(dest, dest, len, &d_key1, &d_IV1, DES_DECRYPT);
-}
-
-void FQTermSSH1DES3::encrypt(const u_char *source, u_char *dest, int len) {
-  DES_ncbc_encrypt(source, dest, len, &d_key1, &d_IV1, DES_ENCRYPT);
-  DES_ncbc_encrypt(dest, dest, len, &d_key2, &d_IV2, DES_DECRYPT);
-  DES_ncbc_encrypt(dest, dest, len, &d_key3, &d_IV3, DES_ENCRYPT);
-}
-
-int FQTermSSH1DES3::getKeySize() const {
-  return 3*DES_KEY_SZ;
-}
-
-int FQTermSSH1DES3::getIVSize() const {
-  return 0;
-}
-
-void FQTermSSH1DES3::setIV(const u_char *data) {
-  memset(d_IV1, 0, sizeof(d_IV1));
-  memset(d_IV2, 0, sizeof(d_IV2));
-  memset(d_IV3, 0, sizeof(d_IV3));
-}
-
-void FQTermSSH1DES3::setKey(const u_char *data) {
-  DES_cblock key;
-  memset(key, 0, sizeof(key));
-  memcpy(key, data, sizeof(key));
-  DES_set_key(&key, &d_key1);
-  data += 8;
-  memset(key, 0, sizeof(key));
-  memcpy(key, data, sizeof(key));
-  DES_set_key(&key, &d_key2);
-  data += 8;
-  memset(key, 0, sizeof(key));
-  memcpy(key, data, sizeof(key));
-  DES_set_key(&key, &d_key3);
-}
-
-
-//==================================================
-// TripleDES-CBC
-//==================================================
-
-FQTermSSH2TripleDESCBC::FQTermSSH2TripleDESCBC() {
-  d_name = "des3-cbc";
-  ctx_ = NULL;
-}
-
-FQTermSSH2TripleDESCBC::~FQTermSSH2TripleDESCBC() {
-  if (ctx_ != NULL) {
-    EVP_CIPHER_CTX_cleanup(ctx_);
-    EVP_CIPHER_CTX_free(ctx_);
-  }
-}
-
-
-int FQTermSSH2TripleDESCBC::blockSize() const {
-  return 8;
-}
-
-int FQTermSSH2TripleDESCBC::getKeySize() const {
-  return 24;  
-}
-
-int FQTermSSH2TripleDESCBC::getIVSize() const {
-  return 8;
-}
-
-void FQTermSSH2TripleDESCBC::setIV(const u_char *data) {
-  memcpy(IV_, data, getIVSize());
-}
-
-void FQTermSSH2TripleDESCBC::setKey(const u_char *data) {
-  memcpy(key_, data, getKeySize());
-}
-
-void FQTermSSH2TripleDESCBC::encrypt(const u_char *source, u_char *dest, int len) {
-  FQ_TRACE("3DES_CBC", 9) << "Start encrypting";  
-  FQ_TRACE("3DES_CBC", 9) << "data len:" << len;
-  FQ_TRACE("3DES_CBC", 9) << "Source: \n" << dumpHexString << std::string((char *)source, len);
-
-  int ret = 0;
-  if (ctx_ == NULL) {
-    // Lazy initialization.
-    ctx_ = EVP_CIPHER_CTX_new();
-    EVP_CIPHER_CTX_init(ctx_);
-    ret = EVP_CipherInit(ctx_, EVP_des_ede3_cbc(), key_, IV_, 1);
-    FQ_VERIFY(ret == 1);
-  }
-
-  ret = EVP_Cipher(ctx_, dest, source, len);
-
-  FQ_VERIFY(ret == 1);
-
-  FQ_TRACE("3DES_CBC", 9) << "Dest: \n" << dumpHexString << std::string((char *)dest, len);
-
-  FQ_TRACE("3DES_CBC", 9) << "IV:\n" << dumpHexString << std::string((char *)IV_, getIVSize());
-  FQ_TRACE("3DES_CBC", 9) << "key:\n" << dumpHexString << std::string((char *)key_, getKeySize());
-
-}
-
-void FQTermSSH2TripleDESCBC::decrypt(const u_char *source, u_char *dest, int len) {
-  FQ_TRACE("3DES_CBC", 9) << "Start dencrypting";  
-  FQ_TRACE("3DES_CBC", 9) << "data len:" << len;
-  FQ_TRACE("3DES_CBC", 9) << "Source: \n" << dumpHexString << std::string((char *)source, len);
-
-  int ret = 0;
-  if (ctx_ == NULL) {
-    // Lazy initialization.
-    ctx_ = EVP_CIPHER_CTX_new();
-    EVP_CIPHER_CTX_init(ctx_);
-    ret = EVP_CipherInit(ctx_, EVP_des_ede3_cbc(), key_, IV_, 0);
-    FQ_VERIFY(ret == 1);
-  }
-
-  ret = EVP_Cipher(ctx_, dest, source, len);
-
-  FQ_VERIFY(ret == 1);
-
-  FQ_TRACE("3DES_CBC", 9) << "Dest: \n" << dumpHexString << std::string((char *)dest, len);
-
-  FQ_TRACE("3DES_CBC", 9) << "IV:\n" << dumpHexString << std::string((char *)IV_, getIVSize());
-  FQ_TRACE("3DES_CBC", 9) << "key:\n" << dumpHexString << std::string((char *)key_, getKeySize());
-}
-
-
-}  // namespace FQTerm
diff --git a/src/protocol/internal/fqterm_ssh_des.h b/src/protocol/internal/fqterm_ssh_des.h
deleted file mode 100644
index ba153f2..0000000
--- a/src/protocol/internal/fqterm_ssh_des.h
+++ /dev/null
@@ -1,74 +0,0 @@
-/***************************************************************************
- *   fqterm, a terminal emulator for both BBS and *nix.                    *
- *   Copyright (C) 2008 fqterm development group.                          *
- *                                                                         *
- *   This program is free software; you can redistribute it and/or modify  *
- *   it under the terms of the GNU General Public License as published by  *
- *   the Free Software Foundation; either version 2 of the License, or     *
- *   (at your option) any later version.                                   *
- *                                                                         *
- *   This program 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 General Public License for more details.                          *
- *                                                                         *
- *   You should have received a copy of the GNU General Public License     *
- *   along with this program; if not, write to the                         *
- *   Free Software Foundation, Inc.,                                       *
- *   51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.               *
- ***************************************************************************/
-
-#ifndef FQTERM_SSH_DES_H
-#define FQTERM_SSH_DES_H
-
-#include <openssl/ssl.h>
-#include <openssl/des.h>
-
-#include "fqterm_ssh_cipher.h"
-#include "fqterm_ssh_types.h"
-
-namespace FQTerm {
-
-class FQTermSSH1DES3: public FQTermSSHCipher {
- private:
-  DES_cblock d_IV1;
-  DES_cblock d_IV2;
-  DES_cblock d_IV3;
-  DES_key_schedule d_key1;
-  DES_key_schedule d_key2;
-  DES_key_schedule d_key3;
- public:
-  FQTermSSH1DES3();
-
-  virtual int blockSize() const;
-  virtual int getKeySize() const;
-  virtual int getIVSize() const;
-  virtual void setIV(const u_char *data);
-  virtual void setKey(const u_char *data);
-  virtual void encrypt(const u_char *source, u_char *dest, int len);
-  virtual void decrypt(const u_char *source, u_char *dest, int len);
-};
-
-class FQTermSSH2TripleDESCBC: public FQTermSSHCipher {
- private:
-  unsigned char IV_[8];
-  unsigned char key_[24];
-
-  EVP_CIPHER_CTX *ctx_;
-
- public:
-  FQTermSSH2TripleDESCBC();
-  ~FQTermSSH2TripleDESCBC();
-
-  virtual int blockSize() const;
-  virtual int getKeySize() const;
-  virtual int getIVSize() const;
-  virtual void setIV(const u_char *data);
-  virtual void setKey(const u_char *data);
-  virtual void encrypt(const u_char *source, u_char *dest, int len);
-  virtual void decrypt(const u_char *source, u_char *dest, int len);
-};
-
-}  // namespace FQTerm
-
-#endif  // FQTERM_SSH_DES_H
diff --git a/src/protocol/internal/fqterm_ssh_packet.cpp b/src/protocol/internal/fqterm_ssh_packet.cpp
index 9c4ff6c..402d1b8 100644
--- a/src/protocol/internal/fqterm_ssh_packet.cpp
+++ b/src/protocol/internal/fqterm_ssh_packet.cpp
@@ -21,7 +21,7 @@
 #include "fqterm_trace.h"
 #include "fqterm_ssh_buffer.h"
 #include "fqterm_ssh_packet.h"
-#include "fqterm_ssh_des.h"
+#include "fqterm_ssh_const.h"
 
 #include "fqterm_serialization.h"
 #include "crc32.h"
@@ -38,8 +38,7 @@ FQTermSSHPacketSender::FQTermSSHPacketSender() {
 
   is_encrypt_ = false;
   cipher_type_ = SSH_CIPHER_NONE;
-  cipher_ = NULL;
-  setEncryptionType(SSH_CIPHER_3DES);
+  cipher = NULL;
 
   is_mac_ = false;
   mac_type_ = FQTERM_SSH_MAC_NONE;
@@ -51,11 +50,10 @@ FQTermSSHPacketSender::FQTermSSHPacketSender() {
 }
 
 FQTermSSHPacketSender::~FQTermSSHPacketSender() {
-  delete buffer_;
-  delete output_buffer_;
-  if (is_encrypt_) {
-    delete cipher_;
-  } 
+	delete buffer_;
+	delete output_buffer_;
+	if (cipher)
+		cipher->cleanup(cipher);
 }
 
 void FQTermSSHPacketSender::putRawData(const char *data, int len) {
@@ -92,23 +90,14 @@ void FQTermSSHPacketSender::write() {
   emit dataToWrite();
 }
 
-void FQTermSSHPacketSender::setEncryptionType(int cipherType) {
-  cipher_type_ = cipherType;
-
-  delete cipher_;
-  cipher_ = NULL;
-
-  switch (cipher_type_) {
-    case SSH_CIPHER_3DES:
-      cipher_ = new FQTermSSH1DES3;
-      break;
-  }
-}
-
 void FQTermSSHPacketSender::startEncryption(const u_char *key, const u_char *IV) {
-  is_encrypt_ = true;
-  cipher_->setIV(IV);
-  cipher_->setKey(key);
+	is_encrypt_ = true;
+
+	if (cipher!=NULL) {
+		memcpy(cipher->IV, IV, cipher->IVSize);
+		memcpy(cipher->key, key, cipher->keySize);
+		cipher->init(cipher);
+	}
 }
 
 void FQTermSSHPacketSender::resetEncryption() {
@@ -146,8 +135,7 @@ FQTermSSHPacketReceiver::FQTermSSHPacketReceiver() {
 
   is_decrypt_ = false;
   cipher_type_ = SSH_CIPHER_NONE;
-  cipher_ = NULL;
-  setEncryptionType(SSH_CIPHER_3DES);
+  cipher = NULL;
 
   is_mac_ = false;
   mac_type_ = FQTERM_SSH_MAC_NONE;
@@ -158,11 +146,11 @@ FQTermSSHPacketReceiver::FQTermSSHPacketReceiver() {
   sequence_no_ = 0;
 }
 
-FQTermSSHPacketReceiver::~FQTermSSHPacketReceiver() {
-  delete buffer_;
-  if (is_decrypt_) {
-    delete cipher_;
-  } 
+FQTermSSHPacketReceiver::~FQTermSSHPacketReceiver()
+{
+	delete buffer_;
+	if (cipher)
+		cipher->cleanup(cipher);
 }
 
 void FQTermSSHPacketReceiver::getRawData(char *data, int length) {
@@ -193,23 +181,14 @@ void FQTermSSHPacketReceiver::consume(int len) {
   buffer_->consume(len);
 }
 
-void FQTermSSHPacketReceiver::setEncryptionType(int cipherType) {
-  cipher_type_ = cipherType;
-
-  delete cipher_;
-  cipher_ = NULL;
-
-  switch (cipher_type_) {
-    case SSH_CIPHER_3DES:
-      cipher_ = new FQTermSSH1DES3;
-      break;
-  }
-}
-
 void FQTermSSHPacketReceiver::startEncryption(const u_char *key, const u_char *IV) {
-  is_decrypt_ = true;
-  cipher_->setIV(IV);
-  cipher_->setKey(key);
+	is_decrypt_ = true;
+
+	if (cipher!=NULL) {
+		memcpy(cipher->IV, IV, cipher->IVSize);
+		memcpy(cipher->key, key, cipher->keySize);
+		cipher->init(cipher);
+	}
 }
 
 void FQTermSSHPacketReceiver::resetEncryption() {
diff --git a/src/protocol/internal/fqterm_ssh_packet.h b/src/protocol/internal/fqterm_ssh_packet.h
index ed5a488..705a11b 100644
--- a/src/protocol/internal/fqterm_ssh_packet.h
+++ b/src/protocol/internal/fqterm_ssh_packet.h
@@ -28,8 +28,8 @@
 #include "fqterm_ssh_types.h"
 #include "fqterm_ssh_buffer.h"
 #include "fqterm_ssh_mac.h"
-#include "fqterm_ssh_cipher.h"
 #include "fqterm_serialization.h"
+#include "ssh_cipher.h"
 
 namespace FQTerm {
 
@@ -38,10 +38,11 @@ class FQTermSSHPacketSender: public QObject {
  public:
   FQTermSSHBuffer *output_buffer_;
   FQTermSSHBuffer *buffer_;
+  ssh_cipher_t *cipher;
 
   FQTermSSHPacketSender();
   virtual ~FQTermSSHPacketSender();
-  
+
   void startPacket(int pkt_type);
   void putByte(int data);
   void putInt(u_int data);
@@ -51,12 +52,11 @@ class FQTermSSHPacketSender: public QObject {
   void putBN2(BIGNUM *bignum);
   void write();
 
-  int getIVSize() const { return cipher_->getIVSize();}
-  int getKeySize() const { return cipher_->getKeySize();}
+  virtual int getIVSize() const { return cipher->IVSize;}
+  virtual int getKeySize() const { return cipher->keySize;}
   int getMacKeySize() const { return mac_->keySize();}
 
  public slots:
-  virtual void setEncryptionType(int cipherType);
   void startEncryption(const u_char *key, const u_char *IV = NULL);
   void resetEncryption();
 
@@ -72,7 +72,6 @@ class FQTermSSHPacketSender: public QObject {
  protected:
   bool is_encrypt_;
   int cipher_type_;
-  FQTermSSHCipher *cipher_;
 
   bool is_mac_;
   int mac_type_;
@@ -89,6 +88,7 @@ class FQTermSSHPacketReceiver: public QObject {
   Q_OBJECT;
  public:
   FQTermSSHBuffer *buffer_;
+  ssh_cipher_t *cipher;
 
   FQTermSSHPacketReceiver();
   virtual ~FQTermSSHPacketReceiver();
@@ -106,13 +106,12 @@ class FQTermSSHPacketReceiver: public QObject {
   void consume(int len);
 
   virtual int packetDataLen() const { return real_data_len_;}
-  int getIVSize() const { return cipher_->getIVSize();}
-  int getKeySize() const { return cipher_->getKeySize();}
+  virtual int getIVSize() const { return cipher->IVSize;}
+  virtual int getKeySize() const { return cipher->keySize;}
   int getMacKeySize() const { return mac_->keySize();}
 
   virtual void parseData(FQTermSSHBuffer *input) = 0;
  public slots:
-  virtual void setEncryptionType(int cipherType);
   void startEncryption(const u_char *key, const u_char *IV = NULL);
   void resetEncryption();
 
@@ -129,7 +128,6 @@ class FQTermSSHPacketReceiver: public QObject {
  protected:
   bool is_decrypt_;
   int cipher_type_;
-  FQTermSSHCipher *cipher_;
 
   bool is_mac_;
   int mac_type_;
diff --git a/src/protocol/internal/ssh_3des-ssh1.c b/src/protocol/internal/ssh_3des-ssh1.c
new file mode 100644
index 0000000..9f78298
--- /dev/null
+++ b/src/protocol/internal/ssh_3des-ssh1.c
@@ -0,0 +1,82 @@
+#include "ssh_cipher.h"
+#include <openssl/des.h>
+#include <string.h>
+
+struct ssh1_3des_priv
+{
+	DES_cblock d_IV1;
+	DES_cblock d_IV2;
+	DES_cblock d_IV3;
+	DES_key_schedule d_key1;
+	DES_key_schedule d_key2;
+	DES_key_schedule d_key3;
+};
+
+static int
+init_3des(SSH_CIPHER* my)
+{
+	struct ssh1_3des_priv *priv = (struct ssh1_3des_priv*)my->priv;
+	const_DES_cblock *key = (const_DES_cblock*)my->key;
+	DES_set_key(key, &priv->d_key1);
+	DES_set_key(key+1, &priv->d_key2);
+	DES_set_key(key+2, &priv->d_key3);
+	memset(priv->d_IV1, 0, sizeof(DES_cblock));
+	memset(priv->d_IV2, 0, sizeof(DES_cblock));
+	memset(priv->d_IV3, 0, sizeof(DES_cblock));
+
+	return 1;
+}
+
+static void
+cleanup(SSH_CIPHER* my)
+{
+	if (my->key!=NULL)
+		free(my->key);
+
+	if (my->priv!=NULL)
+		free(my->priv);
+
+	free(my);
+}
+
+static int
+decrypt(SSH_CIPHER* my, const u_char *source, u_char *dest, size_t len)
+{
+	struct ssh1_3des_priv *priv = (struct ssh1_3des_priv*)my->priv;
+	DES_ncbc_encrypt(source, dest, len, &priv->d_key3, &priv->d_IV3, 0);
+	DES_ncbc_encrypt(dest, dest, len, &priv->d_key2, &priv->d_IV2, 1);
+	DES_ncbc_encrypt(dest, dest, len, &priv->d_key1, &priv->d_IV1, 0);
+	return 1;
+}
+
+static int
+encrypt(SSH_CIPHER* my, const u_char *source, u_char *dest, size_t len)
+{
+	struct ssh1_3des_priv *priv = (struct ssh1_3des_priv*)my->priv;
+	DES_ncbc_encrypt(source, dest, len, &priv->d_key1, &priv->d_IV1, 1);
+	DES_ncbc_encrypt(dest, dest, len, &priv->d_key2, &priv->d_IV2, 0);
+	DES_ncbc_encrypt(dest, dest, len, &priv->d_key3, &priv->d_IV3, 1);
+	return 1;
+}
+
+
+SSH_CIPHER*
+new_3des_ssh1(int enc)
+{
+	SSH_CIPHER *cipher = (SSH_CIPHER*)malloc(sizeof(SSH_CIPHER));
+	cipher->priv = malloc(sizeof(struct ssh1_3des_priv));
+	cipher->blkSize = 8;
+	cipher->IVSize = 0;
+	cipher->keySize = 24;
+	cipher->IV = NULL;
+	cipher->key = (unsigned char*)malloc(24);
+	if (enc)
+		cipher->crypt = encrypt;
+	else
+		cipher->crypt = decrypt;
+
+	cipher->init = init_3des;
+	cipher->cleanup = cleanup;
+
+	return cipher;
+}
diff --git a/src/protocol/internal/ssh_cipher.h b/src/protocol/internal/ssh_cipher.h
new file mode 100644
index 0000000..ec51062
--- /dev/null
+++ b/src/protocol/internal/ssh_cipher.h
@@ -0,0 +1,46 @@
+#ifndef SSH_CIPHER_H
+#define SSH_CIPHER_H
+
+#include <stdlib.h>
+#include <stdint.h>
+#include <openssl/evp.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+	typedef struct ssh_cipher_t SSH_CIPHER;
+	typedef int (*crypt_t)(SSH_CIPHER*, const uint8_t*, uint8_t*, size_t);
+	typedef int (*init_t)(SSH_CIPHER*);
+	typedef void (*cleanup_t)(SSH_CIPHER*);
+
+	struct ssh_cipher_t
+	{
+		/*
+		 * priv is used for things like EVP_CIPHER_CTX and EVP_CIPHER
+		 *
+		 * We use only one crypt function for encrypt or decrypt.
+		 *
+		 * Before using the crypto function, IV and key must
+		 * be set and then init function must be called
+		 */
+		unsigned char *IV;
+		unsigned char *key;
+		void *priv;
+		crypt_t crypt;
+		init_t init;
+		cleanup_t cleanup;
+		size_t blkSize;
+		size_t keySize;
+		size_t IVSize;
+	};
+
+	typedef const EVP_CIPHER*(*SSH_EVP)(void);
+	SSH_CIPHER* new_ssh_cipher_evp(SSH_EVP, size_t key, size_t iv, size_t blk, int enc);
+	SSH_CIPHER* new_3des_ssh1(int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/protocol/internal/ssh_evp_cipher.c b/src/protocol/internal/ssh_evp_cipher.c
new file mode 100644
index 0000000..29f8434
--- /dev/null
+++ b/src/protocol/internal/ssh_evp_cipher.c
@@ -0,0 +1,63 @@
+#include "ssh_cipher.h"
+
+struct evp_priv
+{
+	SSH_EVP evp;
+	EVP_CIPHER_CTX *ctx;
+	int enc;
+};
+
+static int
+cipher_init(SSH_CIPHER* my)
+{
+	struct evp_priv *priv = (struct evp_priv*)my->priv;
+	priv->ctx = EVP_CIPHER_CTX_new();
+	EVP_CIPHER_CTX_init(priv->ctx);
+	return EVP_CipherInit(priv->ctx, priv->evp(), my->key, my->IV, priv->enc);
+}
+
+static int
+do_crypt(SSH_CIPHER* my, const uint8_t* in, uint8_t* out, size_t l)
+{
+	return EVP_Cipher(((struct evp_priv*)my->priv)->ctx, out, in, l);
+}
+
+static void
+cleanup(SSH_CIPHER* my)
+{
+	if (my->IV!=NULL)
+		free(my->IV);
+
+	if (my->key!=NULL)
+		free(my->key);
+
+	if (my->priv!=NULL) {
+		struct evp_priv *priv = my->priv;
+		if (priv->ctx!=NULL)
+			EVP_CIPHER_CTX_free(priv->ctx);
+
+		free(priv);
+	}
+
+	free(my);
+}
+
+SSH_CIPHER*
+new_ssh_cipher_evp(SSH_EVP evp, size_t ks, size_t is, size_t bs, int enc)
+{
+	SSH_CIPHER *cipher = (SSH_CIPHER*)malloc(sizeof(SSH_CIPHER));
+	cipher->priv = malloc(sizeof(struct evp_priv));
+	struct evp_priv *priv = (struct evp_priv*)cipher->priv;
+	priv->evp = evp;
+	priv->enc = enc;
+	priv->ctx = NULL;
+	cipher->blkSize = bs;
+	cipher->keySize = ks;
+	cipher->IVSize = is;
+	cipher->key = (unsigned char*)malloc(ks);
+	cipher->IV = (unsigned char*)malloc(is);
+	cipher->init = cipher_init;
+	cipher->crypt = do_crypt;
+	cipher->cleanup = cleanup;
+	return cipher;
+}

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/chinese/fqterm.git



More information about the Chinese-commits mailing list