[Ttssh2-commit] [3850] 3DES-CTR, BLOWFISH-CTR, CAST128-CTR 共通鍵暗号方式をサポート。

svnno****@sourc***** svnno****@sourc*****
2010年 4月 12日 (月) 17:29:53 JST


Revision: 3850
          http://sourceforge.jp/projects/ttssh2/svn/view?view=rev&revision=3850
Author:   doda
Date:     2010-04-12 17:29:53 +0900 (Mon, 12 Apr 2010)

Log Message:
-----------
3DES-CTR, BLOWFISH-CTR, CAST128-CTR 共通鍵暗号方式をサポート。

Modified Paths:
--------------
    trunk/installer/release/TERATERM.INI
    trunk/ttssh2/ttxssh/cipher-ctr.c
    trunk/ttssh2/ttxssh/crypt.c
    trunk/ttssh2/ttxssh/ssh.c
    trunk/ttssh2/ttxssh/ssh.h
    trunk/ttssh2/ttxssh/ttxssh.c


-------------- next part --------------
Modified: trunk/installer/release/TERATERM.INI
===================================================================
--- trunk/installer/release/TERATERM.INI	2010-04-12 04:17:47 UTC (rev 3849)
+++ trunk/installer/release/TERATERM.INI	2010-04-12 08:29:53 UTC (rev 3850)
@@ -592,11 +592,12 @@
 DefaultForwarding=
 
 ; Cipher algorithm order
-; (2...DES(SSH1),  3...3DES(SSH1), 6...Blowfish(SSH1), 7...3DES-CBC,
-;  8...AES128-CBC, 9...AES192-CBC, :...AES256-CBC, ;...Blowfish,
-;  <...AES128-CTR, =...AES192-CTR, >...AES256-CTR, ?...Arcfour,
-;  @...Arcfour128, A...Arcfour256, B...CAST128-CBC etc)
-CipherOrder=>:=9<87;A@?B3026
+; (2...DES(SSH1),    3...3DES(SSH1),   6...Blowfish(SSH1), 7...3DES-CBC,
+;  8...AES128-CBC,   9...AES192-CBC,   :...AES256-CBC,     ;...Blowfish-CBC,
+;  <...AES128-CTR,   =...AES192-CTR,   >...AES256-CTR,     ?...Arcfour,
+;  @...Arcfour128,   A...Arcfour256,   B...CAST128-CBC,    C...3DES-CTR,
+;  D...BLOWFISH-CTR, E...CAST128-CTR,  etc)
+CipherOrder=>:=9<8C7D;A@?EB3062
 KnownHostsFiles=ssh_known_hosts
 DefaultRhostsLocalUserName=
 DefaultRhostsHostPrivateKeyFile=

Modified: trunk/ttssh2/ttxssh/cipher-ctr.c
===================================================================
--- trunk/ttssh2/ttxssh/cipher-ctr.c	2010-04-12 04:17:47 UTC (rev 3849)
+++ trunk/ttssh2/ttxssh/cipher-ctr.c	2010-04-12 08:29:53 UTC (rev 3850)
@@ -23,15 +23,37 @@
 
 #include <openssl/evp.h>
 #include <openssl/aes.h>
+#include <openssl/des.h>
+#include <openssl/blowfish.h>
+#include <openssl/cast.h>
 
 extern const EVP_CIPHER *evp_aes_128_ctr(void);
 
 struct ssh_aes_ctr_ctx
 {
 	AES_KEY		aes_ctx;
-	unsigned char		aes_counter[AES_BLOCK_SIZE];
+	unsigned char	aes_counter[AES_BLOCK_SIZE];
 };
 
+#define DES_BLOCK_SIZE sizeof(DES_cblock)
+struct ssh_des3_ctr_ctx
+{
+	DES_key_schedule des3_ctx[3];
+	unsigned char	des3_counter[DES_BLOCK_SIZE];
+};
+
+struct ssh_blowfish_ctr_ctx
+{
+	BF_KEY		blowfish_ctx;
+	unsigned char	blowfish_counter[BF_BLOCK];
+};
+
+struct ssh_cast5_ctr_ctx
+{
+	CAST_KEY	cast5_ctx;
+	unsigned char	cast5_counter[CAST_BLOCK];
+};
+
 static void
 ssh_ctr_inc(unsigned char *ctr, unsigned int len)
 {
@@ -42,6 +64,9 @@
 			return;
 }
 
+//============================================================================
+// AES
+//============================================================================
 static int
 ssh_aes_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
 {
@@ -124,3 +149,270 @@
 #endif
 	return (&aes_ctr);
 }
+
+//============================================================================
+// Triple-DES
+//============================================================================
+static int
+ssh_des3_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
+{
+	struct ssh_des3_ctr_ctx *c;
+	unsigned int n = 0;
+	unsigned char buf[DES_BLOCK_SIZE];
+
+	if (len == 0)
+		return (1);
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
+		return (0);
+
+	while ((len--) > 0) {
+		if (n == 0) {
+			memcpy(buf, (unsigned char *)(c->des3_counter), DES_BLOCK_SIZE);
+			DES_encrypt3((DES_LONG *)buf, &c->des3_ctx[0], &c->des3_ctx[1], &c->des3_ctx[2]);
+			ssh_ctr_inc(c->des3_counter, DES_BLOCK_SIZE);
+		}
+		*(dest++) = *(src++) ^ buf[n];
+		n = (n + 1) % DES_BLOCK_SIZE;
+	}
+	return (1);
+}
+
+static int
+ssh_des3_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc)
+{
+	struct ssh_des3_ctr_ctx *c;
+
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+		c = malloc(sizeof(*c));
+		EVP_CIPHER_CTX_set_app_data(ctx, c);
+	}
+	if (key != NULL) {
+		DES_set_key((const_DES_cblock *)key, &c->des3_ctx[0]);
+		DES_set_key((const_DES_cblock *)(key + 8), &c->des3_ctx[1]);
+		DES_set_key((const_DES_cblock *)(key + 16), &c->des3_ctx[2]);
+	}
+
+	if (iv != NULL)
+		memcpy(c->des3_counter, iv, DES_BLOCK_SIZE);
+	return (1);
+}
+
+static int
+ssh_des3_ctr_cleanup(EVP_CIPHER_CTX *ctx)
+{
+	struct ssh_des3_ctr_ctx *c;
+
+	if((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+		memset(c, 0, sizeof(*c));
+		free(c);
+		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+	}
+	return (1);
+}
+
+const EVP_CIPHER *
+evp_des3_ctr(void)
+{
+	static EVP_CIPHER des3_ctr;
+
+	memset(&des3_ctr, 0, sizeof(EVP_CIPHER));
+	des3_ctr.nid = NID_undef;
+	des3_ctr.block_size = DES_BLOCK_SIZE;
+	des3_ctr.iv_len = DES_BLOCK_SIZE;
+	des3_ctr.key_len = 24;
+	des3_ctr.init = ssh_des3_ctr_init;
+	des3_ctr.cleanup = ssh_des3_ctr_cleanup;
+	des3_ctr.do_cipher = ssh_des3_ctr;
+#ifndef SSH_OLD_EVP
+	des3_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
+#endif
+	return (&des3_ctr);
+}
+
+//============================================================================
+// Blowfish
+//============================================================================
+static int
+ssh_bf_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
+{
+	struct ssh_blowfish_ctr_ctx *c;
+	unsigned int n = 0;
+	unsigned char buf[BF_BLOCK];
+	int i, j;
+	BF_LONG tmp[(BF_BLOCK + 3) / 4];
+	unsigned char *p;
+
+	if (len == 0)
+		return (1);
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
+		return (0);
+
+	while ((len--) > 0) {
+		if (n == 0) {
+			for (i = j = 0, p = c->blowfish_counter; i < BF_BLOCK; i += 4, j++) {
+				tmp[j]  = ((BF_LONG)*p++) << 24;
+				tmp[j] |= ((BF_LONG)*p++) << 16;
+				tmp[j] |= ((BF_LONG)*p++) << 8;
+				tmp[j] |= ((BF_LONG)*p++);
+			}
+
+			BF_encrypt(tmp, &c->blowfish_ctx);
+
+			for (i = j = 0, p = buf; i < BF_BLOCK; i += 4, j++) {
+				*p++ = (unsigned char)(tmp[j] >> 24);
+				*p++ = (unsigned char)(tmp[j] >> 16);
+				*p++ = (unsigned char)(tmp[j] >> 8);
+				*p++ = (unsigned char)tmp[j];
+			}
+
+			ssh_ctr_inc(c->blowfish_counter, BF_BLOCK);
+		}
+		*(dest++) = *(src++) ^ buf[n];
+		n = (n + 1) % BF_BLOCK;
+	}
+	return (1);
+}
+
+static int
+ssh_bf_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc)
+{
+	struct ssh_blowfish_ctr_ctx *c;
+
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+		c = malloc(sizeof(*c));
+		EVP_CIPHER_CTX_set_app_data(ctx, c);
+	}
+	if (key != NULL) {
+		BF_set_key(&c->blowfish_ctx, EVP_CIPHER_CTX_key_length(ctx), key);
+	}
+
+	if (iv != NULL)
+		memcpy(c->blowfish_counter, iv, BF_BLOCK);
+	return (1);
+}
+
+static int
+ssh_bf_ctr_cleanup(EVP_CIPHER_CTX *ctx)
+{
+	struct ssh_blowfish_ctr_ctx *c;
+
+	if((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+		memset(c, 0, sizeof(*c));
+		free(c);
+		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+	}
+	return (1);
+}
+
+const EVP_CIPHER *
+evp_bf_ctr(void)
+{
+	static EVP_CIPHER blowfish_ctr;
+
+	memset(&blowfish_ctr, 0, sizeof(EVP_CIPHER));
+	blowfish_ctr.nid = NID_undef;
+	blowfish_ctr.block_size = BF_BLOCK;
+	blowfish_ctr.iv_len = BF_BLOCK;
+	blowfish_ctr.key_len = 16;
+	blowfish_ctr.init = ssh_bf_ctr_init;
+	blowfish_ctr.cleanup = ssh_bf_ctr_cleanup;
+	blowfish_ctr.do_cipher = ssh_bf_ctr;
+#ifndef SSH_OLD_EVP
+	blowfish_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
+#endif
+	return (&blowfish_ctr);
+}
+
+//============================================================================
+// CAST-128
+//============================================================================
+static int
+ssh_cast5_ctr(EVP_CIPHER_CTX *ctx, unsigned char *dest, const unsigned char *src, unsigned int len)
+{
+	struct ssh_cast5_ctr_ctx *c;
+	unsigned int n = 0;
+	unsigned char buf[CAST_BLOCK];
+	int i, j;
+	CAST_LONG tmp[(CAST_BLOCK + 3) / 4];
+	unsigned char *p;
+
+	if (len == 0)
+		return (1);
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL)
+		return (0);
+
+	while ((len--) > 0) {
+		if (n == 0) {
+			for (i = j = 0, p = c->cast5_counter; i < CAST_BLOCK; i += 4, j++) {
+				tmp[j]  = ((CAST_LONG)*p++) << 24;
+				tmp[j] |= ((CAST_LONG)*p++) << 16;
+				tmp[j] |= ((CAST_LONG)*p++) << 8;
+				tmp[j] |= ((CAST_LONG)*p++);
+			}
+
+			CAST_encrypt(tmp, &c->cast5_ctx);
+
+			for (i = j = 0, p = buf; i < CAST_BLOCK; i += 4, j++) {
+				*p++ = (unsigned char)(tmp[j] >> 24);
+				*p++ = (unsigned char)(tmp[j] >> 16);
+				*p++ = (unsigned char)(tmp[j] >> 8);
+				*p++ = (unsigned char)tmp[j];
+			}
+
+			ssh_ctr_inc(c->cast5_counter, CAST_BLOCK);
+		}
+		*(dest++) = *(src++) ^ buf[n];
+		n = (n + 1) % CAST_BLOCK;
+	}
+	return (1);
+}
+
+static int
+ssh_cast5_ctr_init(EVP_CIPHER_CTX *ctx, const unsigned char *key, const unsigned char *iv, int enc)
+{
+	struct ssh_cast5_ctr_ctx *c;
+
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+		c = malloc(sizeof(*c));
+		EVP_CIPHER_CTX_set_app_data(ctx, c);
+	}
+	if (key != NULL) {
+		CAST_set_key(&c->cast5_ctx, EVP_CIPHER_CTX_key_length(ctx), key);
+	}
+
+	if (iv != NULL)
+		memcpy(c->cast5_counter, iv, CAST_BLOCK);
+	return (1);
+}
+
+static int
+ssh_cast5_ctr_cleanup(EVP_CIPHER_CTX *ctx)
+{
+	struct ssh_cast5_ctr_ctx *c;
+
+	if((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+		memset(c, 0, sizeof(*c));
+		free(c);
+		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+	}
+	return (1);
+}
+
+const EVP_CIPHER *
+evp_cast5_ctr(void)
+{
+	static EVP_CIPHER cast5_ctr;
+
+	memset(&cast5_ctr, 0, sizeof(EVP_CIPHER));
+	cast5_ctr.nid = NID_undef;
+	cast5_ctr.block_size = CAST_BLOCK;
+	cast5_ctr.iv_len = CAST_BLOCK;
+	cast5_ctr.key_len = 16;
+	cast5_ctr.init = ssh_cast5_ctr_init;
+	cast5_ctr.cleanup = ssh_cast5_ctr_cleanup;
+	cast5_ctr.do_cipher = ssh_cast5_ctr;
+#ifndef SSH_OLD_EVP
+	cast5_ctr.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH | EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
+#endif
+	return (&cast5_ctr);
+}

Modified: trunk/ttssh2/ttxssh/crypt.c
===================================================================
--- trunk/ttssh2/ttxssh/crypt.c	2010-04-12 04:17:47 UTC (rev 3849)
+++ trunk/ttssh2/ttxssh/crypt.c	2010-04-12 08:29:53 UTC (rev 3850)
@@ -312,7 +312,7 @@
 
 
 // for SSH2(yutaka)
-static void c3DES_CBC_encrypt(PTInstVar pvar, unsigned char FAR * buf,
+static void c3DES_encrypt2(PTInstVar pvar, unsigned char FAR * buf,
                               int bytes)
 {
 	unsigned char *newbuf = malloc(bytes);
@@ -359,7 +359,7 @@
 	free(newbuf);
 }
 
-static void c3DES_CBC_decrypt(PTInstVar pvar, unsigned char FAR * buf,
+static void c3DES_decrypt2(PTInstVar pvar, unsigned char FAR * buf,
                               int bytes)
 {
 	unsigned char *newbuf = malloc(bytes);
@@ -864,7 +864,10 @@
 		            | (1 << SSH2_CIPHER_ARCFOUR)
 		            | (1 << SSH2_CIPHER_ARCFOUR128)
 		            | (1 << SSH2_CIPHER_ARCFOUR256)
-		            | (1 << SSH2_CIPHER_CAST128_CBC);
+		            | (1 << SSH2_CIPHER_CAST128_CBC)
+		            | (1 << SSH2_CIPHER_3DES_CTR)
+		            | (1 << SSH2_CIPHER_BLOWFISH_CTR)
+		            | (1 << SSH2_CIPHER_CAST128_CTR);
 	}
 
 	sender_ciphers &= cipher_mask;
@@ -1329,6 +1332,7 @@
 		switch (pvar->crypt_state.sender_cipher) {
 			// for SSH2(yutaka)
 		case SSH2_CIPHER_3DES_CBC:
+		case SSH2_CIPHER_3DES_CTR:
 			{
 				struct Enc *enc;
 
@@ -1344,7 +1348,7 @@
 				//debug_print(10, enc->key, get_cipher_key_len(pvar->crypt_state.sender_cipher));
 				//debug_print(11, enc->iv, get_cipher_block_size(pvar->crypt_state.sender_cipher));
 
-				pvar->crypt_state.encrypt = c3DES_CBC_encrypt;
+				pvar->crypt_state.encrypt = c3DES_encrypt2;
 				break;
 			}
 
@@ -1375,6 +1379,7 @@
 			}
 
 		case SSH2_CIPHER_BLOWFISH_CBC:
+		case SSH2_CIPHER_BLOWFISH_CTR:
 			{
 				struct Enc *enc;
 
@@ -1416,6 +1421,7 @@
 			}
 
 		case SSH2_CIPHER_CAST128_CBC:
+		case SSH2_CIPHER_CAST128_CTR:
 			{
 				struct Enc *enc;
 
@@ -1471,6 +1477,7 @@
 		switch (pvar->crypt_state.receiver_cipher) {
 			// for SSH2(yutaka)
 		case SSH2_CIPHER_3DES_CBC:
+		case SSH2_CIPHER_3DES_CTR:
 			{
 				struct Enc *enc;
 
@@ -1486,7 +1493,7 @@
 				//debug_print(12, enc->key, get_cipher_key_len(pvar->crypt_state.receiver_cipher));
 				//debug_print(13, enc->iv, get_cipher_block_size(pvar->crypt_state.receiver_cipher));
 
-				pvar->crypt_state.decrypt = c3DES_CBC_decrypt;
+				pvar->crypt_state.decrypt = c3DES_decrypt2;
 				break;
 			}
 
@@ -1517,6 +1524,7 @@
 			}
 
 		case SSH2_CIPHER_BLOWFISH_CBC:
+		case SSH2_CIPHER_BLOWFISH_CTR:
 			{
 				struct Enc *enc;
 
@@ -1559,6 +1567,7 @@
 			}
 
 		case SSH2_CIPHER_CAST128_CBC:
+		case SSH2_CIPHER_CAST128_CTR:
 			{
 				struct Enc *enc;
 
@@ -1677,6 +1686,12 @@
 		return "Arcfour256";
 	case SSH2_CIPHER_CAST128_CBC:
 		return "CAST-128-CBC";
+	case SSH2_CIPHER_3DES_CTR:
+		return "3DES-CTR";
+	case SSH2_CIPHER_BLOWFISH_CTR:
+		return "Blowfish-CTR";
+	case SSH2_CIPHER_CAST128_CTR:
+		return "CAST-128-CTR";
 
 	default:
 		return "Unknown";

Modified: trunk/ttssh2/ttxssh/ssh.c
===================================================================
--- trunk/ttssh2/ttxssh/ssh.c	2010-04-12 04:17:47 UTC (rev 3849)
+++ trunk/ttssh2/ttxssh/ssh.c	2010-04-12 08:29:53 UTC (rev 3850)
@@ -4040,6 +4040,7 @@
 	static char buf[192]; // TODO: malloc()‚É‚·‚ׂ«
 	int cipher;
 	int len, i;
+	char *c_str;
 
 	// ’ʐM’†‚ɂ͌Ă΂ê‚È‚¢‚Í‚¸‚¾‚ªA”O‚Ì‚½‚߁B(2006.6.26 maya)
 	if (pvar->socket != INVALID_SOCKET) {
@@ -4052,42 +4053,56 @@
 		cipher = pvar->settings.CipherOrder[i] - '0';
 		if (cipher == 0) // disabled line
 			break;
-		if (cipher == SSH2_CIPHER_AES128_CBC) {
-			strncat_s(buf, sizeof(buf), "aes128-cbc,", _TRUNCATE);
+		switch (cipher) {
+			case SSH2_CIPHER_3DES_CBC:
+				c_str = "3des-cbc,";
+				break;
+			case SSH2_CIPHER_3DES_CTR:
+				c_str = "3des-ctr,";
+				break;
+			case SSH2_CIPHER_BLOWFISH_CBC:
+				c_str = "blowfish-cbc,";
+				break;
+			case SSH2_CIPHER_BLOWFISH_CTR:
+				c_str = "blowfish-ctr,";
+				break;
+			case SSH2_CIPHER_AES128_CBC:
+				c_str = "aes128-cbc";
+				break;
+			case SSH2_CIPHER_AES192_CBC:
+				c_str = "aes192-cbc,";
+				break;
+			case SSH2_CIPHER_AES256_CBC:
+				c_str = "aes256-cbc,";
+				break;
+			case SSH2_CIPHER_AES128_CTR:
+				c_str = "aes128-ctr,";
+				break;
+			case SSH2_CIPHER_AES192_CTR:
+				c_str = "aes192-ctr,";
+				break;
+			case SSH2_CIPHER_AES256_CTR:
+				c_str = "aes256-ctr,";
+				break;
+			case SSH2_CIPHER_ARCFOUR:
+				c_str = "arcfour,";
+				break;
+			case SSH2_CIPHER_ARCFOUR128:
+				c_str = "arcfour128,";
+				break;
+			case SSH2_CIPHER_ARCFOUR256:
+				c_str = "arcfour256,";
+				break;
+			case SSH2_CIPHER_CAST128_CBC:
+				c_str = "cast128-cbc,";
+				break;
+			case SSH2_CIPHER_CAST128_CTR:
+				c_str = "cast128-ctr,";
+				break;
+			default:
+				continue;
 		}
-		else if (cipher == SSH2_CIPHER_3DES_CBC) {
-			strncat_s(buf, sizeof(buf), "3des-cbc,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_AES192_CBC) {
-			strncat_s(buf, sizeof(buf), "aes192-cbc,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_AES256_CBC) {
-			strncat_s(buf, sizeof(buf), "aes256-cbc,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_BLOWFISH_CBC) {
-			strncat_s(buf, sizeof(buf), "blowfish-cbc,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_AES128_CTR) {
-			strncat_s(buf, sizeof(buf), "aes128-ctr,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_AES192_CTR) {
-			strncat_s(buf, sizeof(buf), "aes192-ctr,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_AES256_CTR) {
-			strncat_s(buf, sizeof(buf), "aes256-ctr,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_ARCFOUR) {
-			strncat_s(buf, sizeof(buf), "arcfour,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_ARCFOUR128) {
-			strncat_s(buf, sizeof(buf), "arcfour128,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_ARCFOUR256) {
-			strncat_s(buf, sizeof(buf), "arcfour256,", _TRUNCATE);
-		}
-		else if (cipher == SSH2_CIPHER_CAST128_CBC) {
-			strncat_s(buf, sizeof(buf), "cast128-cbc,", _TRUNCATE);
-		}
+		strncat_s(buf, sizeof(buf), c_str, _TRUNCATE);
 	}
 	len = strlen(buf);
 	buf[len - 1] = '\0';  // get rid of comma
@@ -4229,6 +4244,12 @@
 		cipher = SSH2_CIPHER_ARCFOUR;
 	} else if (strcmp(str_cipher, "cast128-cbc") == 0) {
 		cipher = SSH2_CIPHER_CAST128_CBC;
+	} else if (strcmp(str_cipher, "3des-ctr") == 0) {
+		cipher = SSH2_CIPHER_3DES_CTR;
+	} else if (strcmp(str_cipher, "blowfish-ctr") == 0) {
+		cipher = SSH2_CIPHER_BLOWFISH_CTR;
+	} else if (strcmp(str_cipher, "cast128-ctr") == 0) {
+		cipher = SSH2_CIPHER_CAST128_CTR;
 	}
 
 	return (cipher);
@@ -6539,6 +6560,9 @@
 	                       | 1 << SSH2_CIPHER_ARCFOUR128
 	                       | 1 << SSH2_CIPHER_ARCFOUR256
 	                       | 1 << SSH2_CIPHER_CAST128_CBC
+	                       | 1 << SSH2_CIPHER_3DES_CTR
+	                       | 1 << SSH2_CIPHER_BLOWFISH_CTR
+	                       | 1 << SSH2_CIPHER_CAST128_CTR
 	);
 	int type = (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA) |
 	           (1 << SSH_AUTH_TIS) | (1 << SSH_AUTH_PAGEANT);

Modified: trunk/ttssh2/ttxssh/ssh.h
===================================================================
--- trunk/ttssh2/ttxssh/ssh.h	2010-04-12 04:17:47 UTC (rev 3849)
+++ trunk/ttssh2/ttxssh/ssh.h	2010-04-12 08:29:53 UTC (rev 3850)
@@ -47,6 +47,9 @@
 
 // from OpenSSH
 extern const EVP_CIPHER *evp_aes_128_ctr(void);
+extern const EVP_CIPHER *evp_des3_ctr(void);
+extern const EVP_CIPHER *evp_bf_ctr(void);
+extern const EVP_CIPHER *evp_cast5_ctr(void);
 
 // yutaka
 #define SSH2_USE
@@ -87,9 +90,10 @@
 	SSH2_CIPHER_AES192_CTR, SSH2_CIPHER_AES256_CTR,
 	SSH2_CIPHER_ARCFOUR, SSH2_CIPHER_ARCFOUR128, SSH2_CIPHER_ARCFOUR256,
 	SSH2_CIPHER_CAST128_CBC,
+	SSH2_CIPHER_3DES_CTR, SSH2_CIPHER_BLOWFISH_CTR, SSH2_CIPHER_CAST128_CTR,
 } SSHCipher;
 
-#define SSH_CIPHER_MAX SSH2_CIPHER_CAST128_CBC
+#define SSH_CIPHER_MAX SSH2_CIPHER_CAST128_CTR
 
 typedef enum {
 	SSH_AUTH_NONE, SSH_AUTH_RHOSTS, SSH_AUTH_RSA, SSH_AUTH_PASSWORD,
@@ -315,6 +319,9 @@
 	{SSH2_CIPHER_ARCFOUR128,   "arcfour128",    8, 16, 1536, EVP_rc4},
 	{SSH2_CIPHER_ARCFOUR256,   "arcfour256",    8, 32, 1536, EVP_rc4},
 	{SSH2_CIPHER_CAST128_CBC,  "cast128-cbc",   8, 16, 0, EVP_cast5_cbc},
+	{SSH2_CIPHER_3DES_CTR,     "3des-ctr",      8, 24, 0, evp_des3_ctr},
+	{SSH2_CIPHER_BLOWFISH_CTR, "blowfish-ctr",  8, 16, 0, evp_bf_ctr},
+	{SSH2_CIPHER_CAST128_CTR,  "cast128-ctr",   8, 16, 0, evp_cast5_ctr},
 	{SSH_CIPHER_NONE, NULL, 0, 0, 0, NULL},
 };
 

Modified: trunk/ttssh2/ttxssh/ttxssh.c
===================================================================
--- trunk/ttssh2/ttxssh/ttxssh.c	2010-04-12 04:17:47 UTC (rev 3849)
+++ trunk/ttssh2/ttxssh/ttxssh.c	2010-04-12 08:29:53 UTC (rev 3850)
@@ -204,11 +204,14 @@
 		SSH2_CIPHER_AES192_CBC,
 		SSH2_CIPHER_AES128_CTR,
 		SSH2_CIPHER_AES128_CBC,
+		SSH2_CIPHER_3DES_CTR,
 		SSH2_CIPHER_3DES_CBC,
+		SSH2_CIPHER_BLOWFISH_CTR,
 		SSH2_CIPHER_BLOWFISH_CBC,
 		SSH2_CIPHER_ARCFOUR256,
 		SSH2_CIPHER_ARCFOUR128,
 		SSH2_CIPHER_ARCFOUR,
+		SSH2_CIPHER_CAST128_CTR,
 		SSH2_CIPHER_CAST128_CBC,
 		SSH_CIPHER_3DES,
 		SSH_CIPHER_NONE,
@@ -2369,6 +2372,12 @@
 		return "Arcfour256(SSH2)";
 	case SSH2_CIPHER_CAST128_CBC:
 		return "CAST128-CBC(SSH2)";
+	case SSH2_CIPHER_3DES_CTR:
+		return "3DES-CTR(SSH2)";
+	case SSH2_CIPHER_BLOWFISH_CTR:
+		return "Blowfish-CTR(SSH2)";
+	case SSH2_CIPHER_CAST128_CTR:
+		return "CAST128-CTR(SSH2)";
 
 	default:
 		return NULL;



Ttssh2-commit メーリングリストの案内