[Ttssh2-commit] [9210] ファイルを分割・コードを移動・関数名を整理・新しい OpenSSH からインポート

Back to archive index
scmno****@osdn***** scmno****@osdn*****
2021年 4月 17日 (土) 17:36:59 JST


Revision: 9210
          https://osdn.net/projects/ttssh2/scm/svn/commits/9210
Author:   nmaya
Date:     2021-04-17 17:36:59 +0900 (Sat, 17 Apr 2021)
Log Message:
-----------
ファイルを分割・コードを移動・関数名を整理・新しい OpenSSH からインポート

- OpenSSH からインポート
  cipher-3des1.c from OpenSSH-7.5p1
  ssherr.c from OpenSSH-8.5p1
  ssherr.h from OpenSSH-8.5p1

Modified Paths:
--------------
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/hosts.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v8.vcproj

Added Paths:
-----------
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c
    branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h

-------------- next part --------------
Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -94,7 +94,7 @@
 }
 
 static LRESULT CALLBACK password_wnd_proc(HWND control, UINT msg,
-										  WPARAM wParam, LPARAM lParam)
+                                          WPARAM wParam, LPARAM lParam)
 {
 	LRESULT result;
 	TPasswordControlData *data = (TPasswordControlData *)GetWindowLongPtr(control, GWLP_USERDATA);
@@ -797,7 +797,7 @@
 
 
 static INT_PTR CALLBACK auth_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
-									  LPARAM lParam)
+                                      LPARAM lParam)
 {
 	const int IDC_TIMER1 = 300; // \x8E\xA9\x93\xAE\x83\x8D\x83O\x83C\x83\x93\x82\xAA\x97L\x8C\xF8\x82ȂƂ\xAB
 	const int IDC_TIMER2 = 301; // \x83T\x83|\x81[\x83g\x82\xB3\x82\xEA\x82Ă\xA2\x82郁\x83\\x83b\x83h\x82\xF0\x8E\xA9\x93\xAE\x83`\x83F\x83b\x83N(CheckAuthListFirst)
@@ -1406,7 +1406,7 @@
 }
 
 static INT_PTR CALLBACK TIS_dlg_proc(HWND dlg, UINT msg, WPARAM wParam,
-									 LPARAM lParam)
+                                     LPARAM lParam)
 {
 	PTInstVar pvar;
 
@@ -1618,7 +1618,7 @@
 }
 
 static INT_PTR CALLBACK default_auth_dlg_proc(HWND dlg, UINT msg,
-											  WPARAM wParam, LPARAM lParam)
+                                              WPARAM wParam, LPARAM lParam)
 {
 	PTInstVar pvar;
 
@@ -1811,7 +1811,7 @@
 				s[key_len] = '\0';
 				UTIL_get_lang_msg("DLG_ABOUT_AUTH_INFO3", pvar, " with %s key from Pageant");
 				_snprintf_s(buf, sizeof(buf), _TRUNCATE, pvar->ts->UIMsg,
-				            ssh_key_type(get_keytype_from_name(s)));
+				            ssh_key_type(get_hostkey_type_from_name(s)));
 				strncat_s(dest, len, buf, _TRUNCATE);
 
 				free(s);

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.h	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/auth.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -41,7 +41,7 @@
   SSHAuthMethod method;
   char *password;
   char *rhosts_client_user;
-  struct Key *key_pair;
+  Key *key_pair;
 } AUTHCred;
 
 typedef enum { GENERIC_AUTH_MODE, TIS_AUTH_MODE } AuthMode;

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,172 @@
+/* Imported from OpenSSH-7.5p1, TeraTerm Project */
+
+/* $OpenBSD: cipher-3des1.c,v 1.12 2015/01/14 10:24:42 markus Exp $ */
+/*
+ * Copyright (c) 2003 Markus Friedl.  All rights reserved.
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+// #include "includes.h"
+
+#include <sys/types.h>
+#include <string.h>
+#include <openssl/evp.h>
+#include <windows.h>
+
+typedef unsigned int u_int;
+typedef unsigned char u_char;
+
+#include "ssherr.h"
+
+/*
+ * This is used by SSH1:
+ *
+ * What kind of triple DES are these 2 routines?
+ *
+ * Why is there a redundant initialization vector?
+ *
+ * If only iv3 was used, then, this would till effect have been
+ * outer-cbc. However, there is also a private iv1 == iv2 which
+ * perhaps makes differential analysis easier. On the other hand, the
+ * private iv1 probably makes the CRC-32 attack ineffective. This is a
+ * result of that there is no longer any known iv1 to use when
+ * choosing the X block.
+ */
+struct ssh1_3des_ctx
+{
+	EVP_CIPHER_CTX  *k1, *k2, *k3;
+};
+
+const EVP_CIPHER * evp_ssh1_3des(void);
+int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
+
+static int ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, int enc)
+{
+	struct ssh1_3des_ctx *c;
+	u_char *k1, *k2, *k3;
+
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+		if ((c = calloc(1, sizeof(*c))) == NULL)
+			return 0;
+		EVP_CIPHER_CTX_set_app_data(ctx, c);
+	}
+	if (key == NULL)
+		return 1;
+	if (enc == -1)
+		enc = EVP_CIPHER_CTX_encrypting(ctx); // ctx->encrypt
+	k1 = k2 = k3 = (u_char *) key;
+	k2 += 8;
+	if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
+		if (enc)
+			k3 += 16;
+		else
+			k1 += 16;
+	}
+	c->k1 = EVP_CIPHER_CTX_new();
+	c->k2 = EVP_CIPHER_CTX_new();
+	c->k3 = EVP_CIPHER_CTX_new();
+	/*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/
+	if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
+	    EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
+	    EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
+		EVP_CIPHER_CTX_free(c->k1);
+		EVP_CIPHER_CTX_free(c->k2);
+		EVP_CIPHER_CTX_free(c->k3);
+		SecureZeroMemory(c, sizeof(*c));
+		free(c);
+		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+		return 0;
+	}
+	return 1;
+}
+
+static int ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
+{
+	struct ssh1_3des_ctx *c;
+
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
+		//error("ssh1_3des_cbc: no context");
+		return 0;
+	}
+	if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 ||
+	    EVP_Cipher(c->k2, dest, dest, len) == 0 ||
+	    EVP_Cipher(c->k3, dest, dest, len) == 0)
+		return 0;
+	return 1;
+}
+
+static int ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
+{
+	struct ssh1_3des_ctx *c;
+
+	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
+		EVP_CIPHER_CTX_free(c->k1);
+		EVP_CIPHER_CTX_free(c->k2);
+		EVP_CIPHER_CTX_free(c->k3);
+		SecureZeroMemory(c, sizeof(*c));
+		free(c);
+		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
+	}
+	return 1;
+}
+
+// ssh1_3des_iv \x82͖\xA2\x8Eg\x97p\x81B
+int ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
+{
+	struct ssh1_3des_ctx *c;
+
+	if (len != 24) {
+		//fatal("%s: bad 3des iv length: %d", __func__, len);
+		return SSH_ERR_INVALID_ARGUMENT;
+	}
+
+	if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL) {
+		//fatal("%s: no 3des context", __func__);
+		return SSH_ERR_INTERNAL_ERROR;
+	}
+
+	if (doset) {
+		//debug3("%s: Installed 3DES IV", __func__);
+		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8);
+		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8);
+		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8);
+	} else {
+		//debug3("%s: Copying 3DES IV", __func__);
+		memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8);
+		memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8);
+		memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8);
+	}
+	return 0;
+}
+
+const EVP_CIPHER *evp_ssh1_3des(void)
+{
+	static EVP_CIPHER *p = NULL;
+
+	if (p == NULL) {
+		p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/8, /*key_len*/16);
+		/*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/
+	}
+	if (p) {
+		EVP_CIPHER_meth_set_iv_length(p, 0);
+		EVP_CIPHER_meth_set_init(p, ssh1_3des_init);
+		EVP_CIPHER_meth_set_cleanup(p, ssh1_3des_cleanup);
+		EVP_CIPHER_meth_set_do_cipher(p, ssh1_3des_cbc);
+		EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH);
+	}
+	return (p);
+}

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,558 @@
+/*
+ * Copyright (c) 1998-2001, Robert O'Callahan
+ * (C) 2004- TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ttxssh.h"
+#include "ssh.h"
+#include "ssherr.h"
+#include "cipher.h"
+#include "kex.h"
+
+#include <openssl/evp.h>
+
+// from cipher-3des.c
+extern const EVP_CIPHER* evp_ssh1_3des(void);
+
+static const struct ssh2cipher ssh2_ciphers[] = {
+	{SSH2_CIPHER_3DES_CBC,        "3des-cbc",         8, 24,    0, 0, 0, EVP_des_ede3_cbc},     // RFC4253
+	{SSH2_CIPHER_AES128_CBC,      "aes128-cbc",      16, 16,    0, 0, 0, EVP_aes_128_cbc},      // RFC4253
+	{SSH2_CIPHER_AES192_CBC,      "aes192-cbc",      16, 24,    0, 0, 0, EVP_aes_192_cbc},      // RFC4253
+	{SSH2_CIPHER_AES256_CBC,      "aes256-cbc",      16, 32,    0, 0, 0, EVP_aes_256_cbc},      // RFC4253
+	{SSH2_CIPHER_BLOWFISH_CBC,    "blowfish-cbc",     8, 16,    0, 0, 0, EVP_bf_cbc},           // RFC4253
+	{SSH2_CIPHER_AES128_CTR,      "aes128-ctr",      16, 16,    0, 0, 0, evp_aes_128_ctr},      // RFC4344
+	{SSH2_CIPHER_AES192_CTR,      "aes192-ctr",      16, 24,    0, 0, 0, evp_aes_128_ctr},      // RFC4344
+	{SSH2_CIPHER_AES256_CTR,      "aes256-ctr",      16, 32,    0, 0, 0, evp_aes_128_ctr},      // RFC4344
+	{SSH2_CIPHER_ARCFOUR,         "arcfour",          8, 16,    0, 0, 0, EVP_rc4},              // RFC4253
+	{SSH2_CIPHER_ARCFOUR128,      "arcfour128",       8, 16, 1536, 0, 0, EVP_rc4},              // RFC4345
+	{SSH2_CIPHER_ARCFOUR256,      "arcfour256",       8, 32, 1536, 0, 0, EVP_rc4},              // RFC4345
+	{SSH2_CIPHER_CAST128_CBC,     "cast128-cbc",      8, 16,    0, 0, 0, EVP_cast5_cbc},        // RFC4253
+	{SSH2_CIPHER_3DES_CTR,        "3des-ctr",         8, 24,    0, 0, 0, evp_des3_ctr},         // RFC4344
+	{SSH2_CIPHER_BLOWFISH_CTR,    "blowfish-ctr",     8, 32,    0, 0, 0, evp_bf_ctr},           // RFC4344
+	{SSH2_CIPHER_CAST128_CTR,     "cast128-ctr",      8, 16,    0, 0, 0, evp_cast5_ctr},        // RFC4344
+	{SSH2_CIPHER_CAMELLIA128_CBC, "camellia128-cbc", 16, 16,    0, 0, 0, EVP_camellia_128_cbc}, // draft-kanno-secsh-camellia-02
+	{SSH2_CIPHER_CAMELLIA192_CBC, "camellia192-cbc", 16, 24,    0, 0, 0, EVP_camellia_192_cbc}, // draft-kanno-secsh-camellia-02
+	{SSH2_CIPHER_CAMELLIA256_CBC, "camellia256-cbc", 16, 32,    0, 0, 0, EVP_camellia_256_cbc}, // draft-kanno-secsh-camellia-02
+	{SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr", 16, 16,    0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
+	{SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr", 16, 24,    0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
+	{SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr", 16, 32,    0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
+#ifdef WITH_CAMELLIA_PRIVATE
+	{SSH2_CIPHER_CAMELLIA128_CBC, "camel****@opens*****", 16, 16, 0,  0,  0, EVP_camellia_128_cbc},
+	{SSH2_CIPHER_CAMELLIA192_CBC, "camel****@opens*****", 16, 24, 0,  0,  0, EVP_camellia_192_cbc},
+	{SSH2_CIPHER_CAMELLIA256_CBC, "camel****@opens*****", 16, 32, 0,  0,  0, EVP_camellia_256_cbc},
+	{SSH2_CIPHER_CAMELLIA128_CTR, "camel****@opens*****", 16, 16, 0,  0,  0, evp_camellia_128_ctr},
+	{SSH2_CIPHER_CAMELLIA192_CTR, "camel****@opens*****", 16, 24, 0,  0,  0, evp_camellia_128_ctr},
+	{SSH2_CIPHER_CAMELLIA256_CTR, "camel****@opens*****", 16, 32, 0,  0,  0, evp_camellia_128_ctr},
+#endif // WITH_CAMELLIA_PRIVATE
+	{SSH2_CIPHER_AES128_GCM,      "aes12****@opens*****",      16, 16, 0, 12, 16, EVP_aes_128_gcm}, // not RFC5647, PROTOCOL of OpenSSH
+	{SSH2_CIPHER_AES256_GCM,      "aes25****@opens*****",      16, 32, 0, 12, 16, EVP_aes_256_gcm}, // not RFC5647, PROTOCOL of OpenSSH
+	{SSH_CIPHER_NONE,             NULL,               0,  0,    0, 0, 0, NULL},
+};
+
+
+int get_cipher_id(const struct ssh2cipher *cipher)
+{
+	if (cipher) {
+		return cipher->id;
+	}
+	else {
+		return 0;
+	}
+}
+
+u_int get_cipher_block_size(const struct ssh2cipher *cipher)
+{
+	u_int blocksize = 0;
+	
+	if (cipher) {
+		blocksize = cipher->block_size;
+	}
+
+	return max(blocksize, 8);
+}
+
+u_int get_cipher_key_len(const struct ssh2cipher *cipher)
+{
+	if (cipher) {
+		return cipher->key_len;
+	}
+	else {
+		return 0;
+	}
+}
+
+u_int get_cipher_discard_len(const struct ssh2cipher *cipher)
+{
+	if (cipher) {
+		return cipher->discard_len;
+	}
+	else {
+		return 0;
+	}
+}
+
+u_int get_cipher_iv_len(const struct ssh2cipher *cipher)
+{
+	if (cipher) {
+		if (cipher->iv_len != 0) {
+			return cipher->iv_len;
+		}
+		else {
+			return cipher->block_size;
+		}
+	}
+	else {
+		return 8; // block_size
+	}
+}
+
+u_int get_cipher_auth_len(const struct ssh2cipher *cipher)
+{
+	if (cipher) {
+		return cipher->auth_len;
+	}
+	else {
+		return 0;
+	}
+}
+
+const EVP_CIPHER *get_cipher_EVP_CIPHER(const struct ssh2cipher *cipher)
+{
+	if (cipher) {
+		return cipher->func();
+	}
+	else {
+		return EVP_enc_null();
+	}
+}
+
+char *get_cipher_string(const struct ssh2cipher *cipher)
+{
+	if (cipher) {
+		return cipher->name;
+	}
+	else {
+		return "unknown";
+	}
+}
+
+// \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x96\xBC\x82\xA9\x82猟\x8D\x{142DC2}\xE9\x81B
+const struct ssh2cipher *get_cipher_by_name(char *name)
+{
+	const struct ssh2cipher *ptr = ssh2_ciphers;
+
+	if (name == NULL || name[0] == '\0')
+		return NULL;
+
+	while (ptr->name != NULL) {
+		if (strcmp(ptr->name, name) == 0) {
+			return ptr;
+		}
+		ptr++;
+	}
+
+	// not found.
+	return NULL;
+}
+
+// \x95\\x8E\xA6\x96\xBC
+char *get_cipher_name(int cipher_id)
+{
+	switch (cipher_id) {
+	case SSH_CIPHER_NONE:
+		return "None";
+	case SSH_CIPHER_3DES:
+		return "3DES (168 key bits)";
+	case SSH_CIPHER_DES:
+		return "DES (56 key bits)";
+	case SSH_CIPHER_BLOWFISH:
+		return "Blowfish (256 key bits)";
+
+	// SSH2 
+	case SSH2_CIPHER_3DES_CBC:
+		return "3des-cbc";
+	case SSH2_CIPHER_AES128_CBC:
+		return "aes128-cbc";
+	case SSH2_CIPHER_AES192_CBC:
+		return "aes192-cbc";
+	case SSH2_CIPHER_AES256_CBC:
+		return "aes256-cbc";
+	case SSH2_CIPHER_BLOWFISH_CBC:
+		return "blowfish-cbc";
+	case SSH2_CIPHER_AES128_CTR:
+		return "aes128-ctr";
+	case SSH2_CIPHER_AES192_CTR:
+		return "aes192-ctr";
+	case SSH2_CIPHER_AES256_CTR:
+		return "aes256-ctr";
+	case SSH2_CIPHER_ARCFOUR:
+		return "arcfour";
+	case SSH2_CIPHER_ARCFOUR128:
+		return "arcfour128";
+	case SSH2_CIPHER_ARCFOUR256:
+		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";
+	case SSH2_CIPHER_CAMELLIA128_CBC:
+		return "camellia128-cbc";
+	case SSH2_CIPHER_CAMELLIA192_CBC:
+		return "camellia192-cbc";
+	case SSH2_CIPHER_CAMELLIA256_CBC:
+		return "camellia256-cbc";
+	case SSH2_CIPHER_CAMELLIA128_CTR:
+		return "camellia128-ctr";
+	case SSH2_CIPHER_CAMELLIA192_CTR:
+		return "camellia192-ctr";
+	case SSH2_CIPHER_CAMELLIA256_CTR:
+		return "camellia256-ctr";
+	case SSH2_CIPHER_AES128_GCM:
+		return "aes12****@opens*****";
+	case SSH2_CIPHER_AES256_GCM:
+		return "aes25****@opens*****";
+
+	default:
+		return "Unknown";
+	}
+}
+
+// \x83\x8A\x83X\x83g\x83{\x83b\x83N\x83X\x95\\x8E\xA6\x96\xBC
+char *get_listbox_cipher_name(int cipher_id, PTInstVar pvar)
+{
+	switch (cipher_id) {
+	case SSH_CIPHER_NONE:
+		UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar,
+		                  "<ciphers below this line are disabled>");
+		return pvar->ts->UIMsg;
+	case SSH_CIPHER_3DES:
+		return "3DES(SSH1)";
+	case SSH_CIPHER_DES:
+		return "DES(SSH1)";
+	case SSH_CIPHER_BLOWFISH:
+		return "Blowfish(SSH1)";
+
+	// for SSH2(yutaka)
+	case SSH2_CIPHER_AES128_CBC:
+		return "aes128-cbc(SSH2)";
+	case SSH2_CIPHER_AES192_CBC:
+		return "aes192-cbc(SSH2)";
+	case SSH2_CIPHER_AES256_CBC:
+		return "aes256-cbc(SSH2)";
+	case SSH2_CIPHER_3DES_CBC:
+		return "3des-cbc(SSH2)";
+	case SSH2_CIPHER_BLOWFISH_CBC:
+		return "blowfish-cbc(SSH2)";
+	case SSH2_CIPHER_AES128_CTR:
+		return "aes128-ctr(SSH2)";
+	case SSH2_CIPHER_AES192_CTR:
+		return "aes192-ctr(SSH2)";
+	case SSH2_CIPHER_AES256_CTR:
+		return "aes256-ctr(SSH2)";
+	case SSH2_CIPHER_ARCFOUR:
+		return "arcfour(SSH2)";
+	case SSH2_CIPHER_ARCFOUR128:
+		return "arcfour128(SSH2)";
+	case SSH2_CIPHER_ARCFOUR256:
+		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)";
+	case SSH2_CIPHER_CAMELLIA128_CBC:
+		return "camellia128-cbc(SSH2)";
+	case SSH2_CIPHER_CAMELLIA192_CBC:
+		return "camellia192-cbc(SSH2)";
+	case SSH2_CIPHER_CAMELLIA256_CBC:
+		return "camellia256-cbc(SSH2)";
+	case SSH2_CIPHER_CAMELLIA128_CTR:
+		return "camellia128-ctr(SSH2)";
+	case SSH2_CIPHER_CAMELLIA192_CTR:
+		return "camellia192-ctr(SSH2)";
+	case SSH2_CIPHER_CAMELLIA256_CTR:
+		return "camellia256-ctr(SSH2)";
+	case SSH2_CIPHER_AES128_GCM:
+		return "aes12****@opens*****(SSH2)";
+	case SSH2_CIPHER_AES256_GCM:
+		return "aes25****@opens*****(SSH2)";
+
+	default:
+		return NULL;
+	}
+}
+
+/*
+ * Remove unsupported cipher or duplicated cipher.
+ * Add unspecified ciphers at the end of list.
+ */
+void normalize_cipher_order(char *buf)
+{
+	/* SSH_CIPHER_NONE means that all ciphers below that one are disabled.
+	   We *never* allow no encryption. */
+	static char default_strings[] = {
+		SSH2_CIPHER_AES256_GCM,
+		SSH2_CIPHER_CAMELLIA256_CTR,
+		SSH2_CIPHER_AES256_CTR,
+		SSH2_CIPHER_CAMELLIA256_CBC,
+		SSH2_CIPHER_AES256_CBC,
+		SSH2_CIPHER_CAMELLIA192_CTR,
+		SSH2_CIPHER_AES192_CTR,
+		SSH2_CIPHER_CAMELLIA192_CBC,
+		SSH2_CIPHER_AES192_CBC,
+		SSH2_CIPHER_AES128_GCM,
+		SSH2_CIPHER_CAMELLIA128_CTR,
+		SSH2_CIPHER_AES128_CTR,
+		SSH2_CIPHER_CAMELLIA128_CBC,
+		SSH2_CIPHER_AES128_CBC,
+		SSH2_CIPHER_3DES_CTR,
+		SSH2_CIPHER_3DES_CBC,
+		SSH2_CIPHER_BLOWFISH_CTR,
+		SSH2_CIPHER_BLOWFISH_CBC,
+		SSH2_CIPHER_CAST128_CTR,
+		SSH2_CIPHER_CAST128_CBC,
+		SSH_CIPHER_3DES,
+		SSH_CIPHER_NONE,
+		SSH2_CIPHER_ARCFOUR256,
+		SSH2_CIPHER_ARCFOUR128,
+		SSH2_CIPHER_ARCFOUR,
+		SSH_CIPHER_BLOWFISH,
+		SSH_CIPHER_DES,
+		0, 0, 0 // Dummy for SSH_CIPHER_IDEA, SSH_CIPHER_TSS, SSH_CIPHER_RC4
+	};
+
+	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
+}
+
+const struct ssh2cipher *choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal)
+{
+	char str_cipher[32];
+	const struct ssh2cipher *ptr = ssh2_ciphers;
+
+	choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher));
+	return get_cipher_by_name(str_cipher);
+}
+
+void SSH2_update_cipher_myproposal(PTInstVar pvar)
+{
+	static char buf[512]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
+	int cipher;
+	int len, i;
+	char *c_str;
+
+	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
+	if (pvar->socket != INVALID_SOCKET) {
+		return;
+	}
+
+	// \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B(2004.11.6 yutaka)
+	buf[0] = '\0';
+	for (i = 0 ; pvar->settings.CipherOrder[i] != 0 ; i++) {
+		cipher = pvar->settings.CipherOrder[i] - '0';
+		if (cipher == 0) // disabled line
+			break;
+		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;
+#ifdef WITH_CAMELLIA_PRIVATE
+			case SSH2_CIPHER_CAMELLIA128_CBC:
+				c_str = "camellia128-cbc,camel****@opens*****,";
+				break;
+			case SSH2_CIPHER_CAMELLIA192_CBC:
+				c_str = "camellia192-cbc,camel****@opens*****,";
+				break;
+			case SSH2_CIPHER_CAMELLIA256_CBC:
+				c_str = "camellia256-cbc,camel****@opens*****,";
+				break;
+			case SSH2_CIPHER_CAMELLIA128_CTR:
+				c_str = "camellia128-ctr,camel****@opens*****,";
+				break;
+			case SSH2_CIPHER_CAMELLIA192_CTR:
+				c_str = "camellia192-ctr,camel****@opens*****,";
+				break;
+			case SSH2_CIPHER_CAMELLIA256_CTR:
+				c_str = "camellia256-ctr,camel****@opens*****,";
+				break;
+#endif // WITH_CAMELLIA_PRIVATE
+			case SSH2_CIPHER_CAMELLIA128_CBC:
+				c_str = "camellia128-cbc,";
+				break;
+			case SSH2_CIPHER_CAMELLIA192_CBC:
+				c_str = "camellia192-cbc,";
+				break;
+			case SSH2_CIPHER_CAMELLIA256_CBC:
+				c_str = "camellia256-cbc,";
+				break;
+			case SSH2_CIPHER_CAMELLIA128_CTR:
+				c_str = "camellia128-ctr,";
+				break;
+			case SSH2_CIPHER_CAMELLIA192_CTR:
+				c_str = "camellia192-ctr,";
+				break;
+			case SSH2_CIPHER_CAMELLIA256_CTR:
+				c_str = "camellia256-ctr,";
+				break;
+			case SSH2_CIPHER_AES128_GCM:
+				c_str = "aes12****@opens*****,";
+				break;
+			case SSH2_CIPHER_AES256_GCM:
+				c_str = "aes25****@opens*****,";
+				break;
+			default:
+				continue;
+		}
+		strncat_s(buf, sizeof(buf), c_str, _TRUNCATE);
+	}
+	len = strlen(buf);
+	if (len > 0)
+		buf[len - 1] = '\0';  // get rid of comma
+	myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf;  // Client To Server
+	myproposal[PROPOSAL_ENC_ALGS_STOC] = buf;  // Server To Client
+}
+
+
+//
+// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̏\x89\x8A\xFA\x89\xBB
+//
+void cipher_init_SSH2(EVP_CIPHER_CTX *evp,
+                      const u_char *key, u_int keylen,
+                      const u_char *iv, u_int ivlen,
+                      int do_encrypt,
+                      const EVP_CIPHER *type,
+                      int discard_len,
+                      unsigned int authlen,
+                      PTInstVar pvar)
+{
+	int klen;
+	unsigned char *junk = NULL, *discard = NULL;
+	char tmp[80];
+
+	EVP_CIPHER_CTX_reset(evp);
+	
+	if (EVP_CipherInit(evp, type, NULL, (u_char *)iv, (do_encrypt == CIPHER_ENCRYPT)) == 0) {
+		UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
+		_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 1);
+		notify_fatal_error(pvar, tmp, TRUE);
+		return;
+	}
+	if (authlen &&
+	    !EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) {
+		UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
+		_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 2);
+		notify_fatal_error(pvar, tmp, TRUE);
+		return;
+	}
+	klen = EVP_CIPHER_CTX_key_length(evp);
+	if (klen > 0 && keylen != (u_int)klen) {
+		if (EVP_CIPHER_CTX_set_key_length(evp, keylen) == 0) {
+			UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
+			_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 3);
+			notify_fatal_error(pvar, tmp, TRUE);
+			return;
+		}
+	}
+	if (EVP_CipherInit(evp, NULL, (u_char *)key, NULL, -1) == 0) {
+		UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
+		_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 4);
+		notify_fatal_error(pvar, tmp, TRUE);
+		return;
+	}
+
+	if (discard_len > 0) {
+		junk = malloc(discard_len);
+		discard = malloc(discard_len);
+		if (junk == NULL || discard == NULL ||
+		    EVP_Cipher(evp, discard, junk, discard_len) == 0) {
+			UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
+			_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 5);
+			notify_fatal_error(pvar, tmp, TRUE);
+		}
+		else {
+			SecureZeroMemory(discard, discard_len);
+		}
+		free(junk);
+		free(discard);
+	}
+}
+
+//
+// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̔j\x8A\xFC
+///
+void cipher_free_SSH2(EVP_CIPHER_CTX *evp)
+{
+	EVP_CIPHER_CTX_free(evp);
+}

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -1,5 +1,7 @@
-/*	$OpenBSD: cipher.h,v 1.34 2003/11/10 16:23:41 jakob Exp $	*/
+/* Imported from OpenSSH-8.5p1, TeraTerm Project */
 
+/* $OpenBSD: cipher.h,v 1.44 2014/01/25 10:12:50 dtucker Exp $ */
+
 /*
  * Author: Tatu Ylonen <ylo****@cs*****>
  * Copyright (c) 1995 Tatu Ylonen <ylo****@cs*****>, Espoo, Finland
@@ -37,6 +39,9 @@
 #ifndef CIPHER_H
 #define CIPHER_H
 
+typedef unsigned int u_int;
+typedef unsigned char u_char;
+
 #include <openssl/evp.h>
 /*
  * Cipher types for SSH-1.  New types can be added, but old types should not
@@ -45,49 +50,78 @@
 #define SSH_CIPHER_SSH2		-3
 #define SSH_CIPHER_ILLEGAL	-2	/* No valid cipher selected. */
 #define SSH_CIPHER_NOT_SET	-1	/* None selected (invalid number). */
-#define SSH_CIPHER_NONE		0	/* no encryption */
-#define SSH_CIPHER_IDEA		1	/* IDEA CFB */
-#define SSH_CIPHER_DES		2	/* DES CBC */
-#define SSH_CIPHER_3DES		3	/* 3DES CBC */
-#define SSH_CIPHER_BROKEN_TSS	4	/* TRI's Simple Stream encryption CBC */
-#define SSH_CIPHER_BROKEN_RC4	5	/* Alleged RC4 */
-#define SSH_CIPHER_BLOWFISH	6
-#define SSH_CIPHER_RESERVED	7
+//#define SSH_CIPHER_NONE		0	/* no encryption */
+//#define SSH_CIPHER_IDEA		1	/* IDEA CFB */
+//#define SSH_CIPHER_DES		2	/* DES CBC */
+//#define SSH_CIPHER_3DES		3	/* 3DES CBC */
+//#define SSH_CIPHER_BROKEN_TSS	4	/* TRI's Simple Stream encryption CBC */
+//#define SSH_CIPHER_BROKEN_RC4	5	/* Alleged RC4 */
+//#define SSH_CIPHER_BLOWFISH	6
+//#define SSH_CIPHER_RESERVED	7
 
 #define CIPHER_ENCRYPT		1
 #define CIPHER_DECRYPT		0
 
-typedef struct Cipher Cipher;
-typedef struct CipherContext CipherContext;
 
-struct Cipher;
-struct CipherContext {
-	int	plaintext;
+typedef enum {
+	// SSH1
+	SSH_CIPHER_NONE, SSH_CIPHER_IDEA, SSH_CIPHER_DES, SSH_CIPHER_3DES,
+	SSH_CIPHER_TSS, SSH_CIPHER_RC4, SSH_CIPHER_BLOWFISH,
+	// SSH2
+	SSH2_CIPHER_3DES_CBC, SSH2_CIPHER_AES128_CBC,
+	SSH2_CIPHER_AES192_CBC, SSH2_CIPHER_AES256_CBC,
+	SSH2_CIPHER_BLOWFISH_CBC, SSH2_CIPHER_AES128_CTR,
+	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,
+	SSH2_CIPHER_CAMELLIA128_CBC, SSH2_CIPHER_CAMELLIA192_CBC, SSH2_CIPHER_CAMELLIA256_CBC,
+	SSH2_CIPHER_CAMELLIA128_CTR, SSH2_CIPHER_CAMELLIA192_CTR, SSH2_CIPHER_CAMELLIA256_CTR,
+	SSH2_CIPHER_AES128_GCM, SSH2_CIPHER_AES256_GCM, SSH2_CIPHER_CHACHAPOLY,
+	SSH_CIPHER_MAX = SSH2_CIPHER_CHACHAPOLY,
+} SSHCipherId;
+
+struct ssh2cipher {
+	SSHCipherId id;
+	char *name;
+	u_int block_size;
+	u_int key_len;
+	u_int discard_len;
+	u_int iv_len;
+	u_int auth_len;
+	const EVP_CIPHER *(*func)(void);
+};
+
+struct sshcipher_ctx {
+	// TTSSH \x82ł\xCD SSH_CIPHER_NONE \x82\xAA\x96\xB3\x8C\xF8\x82Ȃ̂ŁAplaintext \x82͎g\x97p\x82\xB3\x82\xEA\x82Ȃ\xA2
+	// int	plaintext;
+	// TTSSH \x82ł\xCD CRYPT_encrypt_aead(), CRYPT_decrypt_aead() \x82\xAA\x95ʂ\xEA\x82Ă\xA2\x82\xC4 encrypt \x82Ő؂\xE8\x91ւ\xA6\x82Ȃ\xA2\x82̂Ŏg\x97p\x82\xB3\x82\xEA\x82Ȃ\xA2
+	// int	encrypt;
 	EVP_CIPHER_CTX *evp;
-	Cipher *cipher;
+	// struct chachapoly_ctx *cp_ctx;
+	// OpenSSH \x82\xC5 ifndef WITH_OPENSSL \x82̎\x9E\x82Ɏg\x97p\x82\xB3\x82\xEA\x82\xE9\x82\xE0\x82̂Ȃ̂ŁAac_ctx \x82͎g\x97p\x82\xB3\x82\xEA\x82Ȃ\xA2
+	// aesctr_ctx ac_ctx; /* XXX union with evp? */
+	// OpenSSH \x82ł\xCD const struct sshcipher *cipher;
+	const struct ssh2cipher *cipher;
 };
 
-u_int	 cipher_mask_ssh1(int);
-Cipher	*cipher_by_name(const char *);
-Cipher	*cipher_by_number(int);
-int	 cipher_number(const char *);
-char	*cipher_name(int);
-int	 ciphers_valid(const char *);
-void	 cipher_init(CipherContext *, Cipher *, const u_char *, u_int,
-    const u_char *, u_int, int);
-void	 cipher_crypt(CipherContext *, u_char *, const u_char *, u_int);
-void	 cipher_cleanup(CipherContext *);
-void	 cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
-u_int	 cipher_blocksize(const Cipher *);
-u_int	 cipher_keylen(const Cipher *);
 
-u_int	 cipher_get_number(const Cipher *);
-void	 cipher_get_keyiv(CipherContext *, u_char *, u_int);
-void	 cipher_set_keyiv(CipherContext *, u_char *);
-int	 cipher_get_keyiv_len(const CipherContext *);
-int	 cipher_get_keycontext(const CipherContext *, u_char *);
-void	 cipher_set_keycontext(CipherContext *, u_char *);
+int get_cipher_id(const struct ssh2cipher *cipher);
+u_int get_cipher_block_size(const struct ssh2cipher *cipher);
+u_int get_cipher_key_len(const struct ssh2cipher *cipher);
+u_int get_cipher_discard_len(const struct ssh2cipher *cipher);
+u_int get_cipher_iv_len(const struct ssh2cipher *cipher);
+u_int get_cipher_auth_len(const struct ssh2cipher *cipher);
+const EVP_CIPHER *get_cipher_EVP_CIPHER(const struct ssh2cipher *cipher);
+char *get_cipher_string(const struct ssh2cipher *cipher);
+const struct ssh2cipher* get_cipher_by_name(char *name);
+char *get_cipher_name(int cipher_id);
+char *get_listbox_cipher_name(int cipher_id, PTInstVar pvar);
 
+void normalize_cipher_order(char *buf);
+const struct ssh2cipher *choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal);
+void SSH2_update_cipher_myproposal(PTInstVar pvar);
+
 void cipher_init_SSH2(
 	EVP_CIPHER_CTX *evp,
 	const u_char *key, u_int keylen,
@@ -98,7 +132,6 @@
 	unsigned int authlen,
 	PTInstVar pvar
 );
-
 void cipher_free_SSH2(EVP_CIPHER_CTX *evp);
 
 #endif				/* CIPHER_H */

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,129 @@
+/*
+ * (C) 2021- TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ttxssh.h"
+#include "comp.h"
+#include "kex.h"
+
+
+struct ssh2_comp_t {
+	compression_type type;
+	char *name;
+};
+
+static const struct ssh2_comp_t ssh2_comps[] = {
+	{COMP_NOCOMP,  "none"},             // RFC4253
+	{COMP_ZLIB,    "zlib"},             // RFC4253
+	{COMP_DELAYED, "zlib****@opens*****"},
+	{COMP_NONE,    NULL},
+};
+
+
+char* get_ssh2_comp_name(compression_type type)
+{
+	const struct ssh2_comp_t *ptr = ssh2_comps;
+
+	while (ptr->name != NULL) {
+		if (type == ptr->type) {
+			return ptr->name;
+		}
+		ptr++;
+	}
+
+	// not found.
+	return "unknown";
+}
+
+void normalize_comp_order(char *buf)
+{
+	static char default_strings[] = {
+		COMP_DELAYED,
+		COMP_ZLIB,
+		COMP_NOCOMP,
+		COMP_NONE,
+	};
+
+	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
+}
+
+compression_type choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal)
+{
+	compression_type type = COMP_UNKNOWN;
+	char str_comp[20];
+	const struct ssh2_comp_t *ptr = ssh2_comps;
+
+	choose_SSH2_proposal(server_proposal, my_proposal, str_comp, sizeof(str_comp));
+
+	while (ptr->name != NULL) {
+		if (strcmp(ptr->name, str_comp) == 0) {
+			type = ptr->type;
+			break;
+		}
+		ptr++;
+	}
+
+	return (type);
+}
+
+void SSH2_update_compression_myproposal(PTInstVar pvar)
+{
+	static char buf[128]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
+	int index;
+	int len, i;
+
+	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
+	if (pvar->socket != INVALID_SOCKET) {
+		return;
+	}
+
+	// \x88\xB3\x8Fk\x83\x8C\x83x\x83\x8B\x82ɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B(2005.7.9 yutaka)
+	buf[0] = '\0';
+	for (i = 0 ; pvar->settings.CompOrder[i] != 0 ; i++) {
+		index = pvar->settings.CompOrder[i] - '0';
+		if (index == COMP_NONE) // disabled line
+			break;
+		strncat_s(buf, sizeof(buf), get_ssh2_comp_name(index), _TRUNCATE);
+		strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
+	}
+	len = strlen(buf);
+	if (len > 0)
+		buf[len - 1] = '\0';  // get rid of comma
+
+	// \x88\xB3\x8Fk\x8Ew\x92肪\x82Ȃ\xA2\x8Fꍇ\x82́A\x88\xB3\x8Fk\x83\x8C\x83x\x83\x8B\x82𖳏\xF0\x8C\x8F\x82Ƀ[\x83\x8D\x82ɂ\xB7\x82\xE9\x81B
+	if (buf[0] == '\0') {
+		pvar->settings.CompressionLevel = 0;
+	}
+
+	if (pvar->settings.CompressionLevel == 0) {
+		_snprintf_s(buf, sizeof(buf), _TRUNCATE, get_ssh2_comp_name(COMP_NOCOMP));
+	}
+	if (buf[0] != '\0') {
+		myproposal[PROPOSAL_COMP_ALGS_CTOS] = buf;  // Client To Server
+		myproposal[PROPOSAL_COMP_ALGS_STOC] = buf;  // Server To Client
+	}
+}

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,49 @@
+/*
+ * (C) 2021- TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SSHCOMP_H
+#define SSHCOMP_H
+
+#include "ttxssh.h"
+
+typedef enum {
+	COMP_NONE,      /* disabled line */
+	COMP_NOCOMP,
+	COMP_ZLIB,
+	COMP_DELAYED,
+	COMP_UNKNOWN,
+	COMP_MAX = COMP_UNKNOWN,
+} compression_type;
+
+char* get_ssh2_comp_name(compression_type type);
+
+void normalize_comp_order(char *buf);
+compression_type choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal);
+void SSH2_update_compression_myproposal(PTInstVar pvar);
+
+#endif /* SSHCOMP_H */

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -75,8 +75,6 @@
 static unsigned char *encbuff = NULL;
 static unsigned int encbufflen = 0;
 
-static char *get_cipher_name(int cipher);
-
 static void crc_update(uint32 *a, uint32 b)
 {
 	b ^= *a;
@@ -296,10 +294,10 @@
 	memcpy(data+aadlen, encbuff, bytes);
 
 	if (EVP_Cipher(evp, NULL, NULL, 0) < 0)
-		return FALSE;
-	else
-		return TRUE;
+		goto err;
 
+	return TRUE;
+
 err:
 	UTIL_get_lang_msg("MSG_DECRYPT_ERROR2", pvar, "%s decrypt error(2)");
 	_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg,
@@ -802,13 +800,13 @@
 			pvar->crypt_state.sender_cipher = SSH_CIPHER_NONE;
 		}
 		else {
-			pvar->crypt_state.sender_cipher = pvar->ciphers[MODE_OUT]->id;
+			pvar->crypt_state.sender_cipher = get_cipher_id(pvar->ciphers[MODE_OUT]);
 		}
 		if (pvar->ciphers[MODE_IN] == NULL) {
 			pvar->crypt_state.receiver_cipher = SSH_CIPHER_NONE;
 		}
 		else {
-			pvar->crypt_state.receiver_cipher = pvar->ciphers[MODE_IN]->id;
+			pvar->crypt_state.receiver_cipher = get_cipher_id(pvar->ciphers[MODE_IN]);
 		}
 	}
 
@@ -1046,98 +1044,12 @@
 	SecureZeroMemory(state->ivec, 8);
 }
 
-
-//
-// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̏\x89\x8A\xFA\x89\xBB
-//
-void cipher_init_SSH2(EVP_CIPHER_CTX *evp,
-                      const u_char *key, u_int keylen,
-                      const u_char *iv, u_int ivlen,
-                      int encrypt,
-                      const EVP_CIPHER *type,
-                      int discard_len,
-                      unsigned int authlen,
-                      PTInstVar pvar)
-{
-	int klen;
-	char tmp[80];
-	unsigned char *junk = NULL, *discard = NULL;
-
-	EVP_CIPHER_CTX_reset(evp);
-	if (EVP_CipherInit(evp, type, NULL, NULL, (encrypt == CIPHER_ENCRYPT)) == 0) {
-		UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
-		_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 1);
-		notify_fatal_error(pvar, tmp, TRUE);
-		return;
-	}
-
-	if (authlen > 0 && !EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_SET_IVLEN, ivlen, NULL)) {
-		UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
-		_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 2);
-		notify_fatal_error(pvar, tmp, TRUE);
-		return;
-	}
-	if (EVP_CipherInit(evp, NULL, NULL, (u_char *)iv, -1) == 0) {
-		UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
-		_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 3);
-		notify_fatal_error(pvar, tmp, TRUE);
-		return;
-	}
-	if (authlen > 0 && !EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_SET_IV_FIXED, -1, (u_char *)iv)) {
-		UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
-		_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 4);
-		notify_fatal_error(pvar, tmp, TRUE);
-		return;
-	}
-
-	klen = EVP_CIPHER_CTX_key_length(evp);
-	if (klen > 0 && keylen != klen) {
-		if (EVP_CIPHER_CTX_set_key_length(evp, keylen) == 0) {
-			UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
-			_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 5);
-			notify_fatal_error(pvar, tmp, TRUE);
-			return;
-		}
-	}
-	if (EVP_CipherInit(evp, NULL, (u_char *)key, NULL, -1) == 0) {
-		UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
-		_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 6);
-		notify_fatal_error(pvar, tmp, TRUE);
-		return;
-	}
-
-	if (discard_len > 0) {
-		junk = malloc(discard_len);
-		discard = malloc(discard_len);
-		if (junk == NULL || discard == NULL ||
-		    EVP_Cipher(evp, discard, junk, discard_len) == 0) {
-			UTIL_get_lang_msg("MSG_CIPHER_INIT_ERROR", pvar, "Cipher initialize error(%d)");
-			_snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 7);
-			notify_fatal_error(pvar, tmp, TRUE);
-		}
-		else {
-			SecureZeroMemory(discard, discard_len);
-		}
-		free(junk);
-		free(discard);
-	}
-}
-
-//
-// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̔j\x8A\xFC
-//
-void cipher_free_SSH2(EVP_CIPHER_CTX *evp)
-{
-	EVP_CIPHER_CTX_free(evp);
-}
-
-
 BOOL CRYPT_start_encryption(PTInstVar pvar, int sender_flag, int receiver_flag)
 {
 	struct Enc *enc;
 	char *encryption_key = pvar->crypt_state.sender_cipher_key;
 	char *decryption_key = pvar->crypt_state.receiver_cipher_key;
-	SSH2Cipher *cipher;
+	const struct ssh2cipher *cipher;
 	BOOL isOK = TRUE;
 
 	if (sender_flag) {
@@ -1262,71 +1174,6 @@
 		HASH_MINSIZE / HASH_ENTRYSIZE;
 }
 
-static char *get_cipher_name(int cipher)
-{
-	switch (cipher) {
-	case SSH_CIPHER_NONE:
-		return "None";
-	case SSH_CIPHER_3DES:
-		return "3DES (168 key bits)";
-	case SSH_CIPHER_DES:
-		return "DES (56 key bits)";
-	case SSH_CIPHER_BLOWFISH:
-		return "Blowfish (256 key bits)";
-
-	// SSH2 
-	case SSH2_CIPHER_3DES_CBC:
-		return "3des-cbc";
-	case SSH2_CIPHER_AES128_CBC:
-		return "aes128-cbc";
-	case SSH2_CIPHER_AES192_CBC:
-		return "aes192-cbc";
-	case SSH2_CIPHER_AES256_CBC:
-		return "aes256-cbc";
-	case SSH2_CIPHER_BLOWFISH_CBC:
-		return "blowfish-cbc";
-	case SSH2_CIPHER_AES128_CTR:
-		return "aes128-ctr";
-	case SSH2_CIPHER_AES192_CTR:
-		return "aes192-ctr";
-	case SSH2_CIPHER_AES256_CTR:
-		return "aes256-ctr";
-	case SSH2_CIPHER_ARCFOUR:
-		return "arcfour";
-	case SSH2_CIPHER_ARCFOUR128:
-		return "arcfour128";
-	case SSH2_CIPHER_ARCFOUR256:
-		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";
-	case SSH2_CIPHER_CAMELLIA128_CBC:
-		return "camellia128-cbc";
-	case SSH2_CIPHER_CAMELLIA192_CBC:
-		return "camellia192-cbc";
-	case SSH2_CIPHER_CAMELLIA256_CBC:
-		return "camellia256-cbc";
-	case SSH2_CIPHER_CAMELLIA128_CTR:
-		return "camellia128-ctr";
-	case SSH2_CIPHER_CAMELLIA192_CTR:
-		return "camellia192-ctr";
-	case SSH2_CIPHER_CAMELLIA256_CTR:
-		return "camellia256-ctr";
-	case SSH2_CIPHER_AES128_GCM:
-		return "aes12****@opens*****";
-	case SSH2_CIPHER_AES256_GCM:
-		return "aes25****@opens*****";
-
-	default:
-		return "Unknown";
-	}
-}
-
 void CRYPT_get_cipher_info(PTInstVar pvar, char *dest, int len)
 {
 	UTIL_get_lang_msg("DLG_ABOUT_CIPHER_INFO", pvar,

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,186 @@
+/*
+ * (C) 2021- TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ttxssh.h"
+#include "hostkey.h"
+#include "kex.h"
+
+
+struct ssh2_host_key_t {
+	ssh_keytype type;
+	char *name;
+};
+
+static const struct ssh2_host_key_t ssh2_host_key[] = {
+	{KEY_RSA1,     "ssh-rsa1"},            // for SSH1 only
+	{KEY_RSA,      "ssh-rsa"},             // RFC4253
+	{KEY_DSA,      "ssh-dss"},             // RFC4253
+	{KEY_ECDSA256, "ecdsa-sha2-nistp256"}, // RFC5656
+	{KEY_ECDSA384, "ecdsa-sha2-nistp384"}, // RFC5656
+	{KEY_ECDSA521, "ecdsa-sha2-nistp521"}, // RFC5656
+	{KEY_ED25519,  "ssh-ed25519"},         // draft-bjh21-ssh-ed25519-02
+	{KEY_UNSPEC,   "ssh-unknown"},
+	{KEY_NONE,     NULL},
+};
+
+struct ssh_digest_t {
+	digest_algorithm id;
+	char *name;
+};
+
+/* NB. Indexed directly by algorithm number */
+static const struct ssh_digest_t ssh_digests[] = {
+	{ SSH_DIGEST_MD5,       "MD5" },
+	{ SSH_DIGEST_RIPEMD160, "RIPEMD160" },
+	{ SSH_DIGEST_SHA1,      "SHA1" },
+	{ SSH_DIGEST_SHA256,    "SHA256" },
+	{ SSH_DIGEST_SHA384,    "SHA384" },
+	{ SSH_DIGEST_SHA512,    "SHA512" },
+	{ SSH_DIGEST_MAX,       NULL },
+};
+
+
+ssh_keytype get_hostkey_type_from_name(char *name)
+{
+	if (strcmp(name, "rsa1") == 0) {
+		return KEY_RSA1;
+	} else if (strcmp(name, "rsa") == 0) {
+		return KEY_RSA;
+	} else if (strcmp(name, "dsa") == 0) {
+		return KEY_DSA;
+	} else if (strcmp(name, "ssh-rsa") == 0) {
+		return KEY_RSA;
+	} else if (strcmp(name, "ssh-dss") == 0) {
+		return KEY_DSA;
+	} else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
+		return KEY_ECDSA256;
+	} else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
+		return KEY_ECDSA384;
+	} else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
+		return KEY_ECDSA521;
+	} else if (strcmp(name, "ssh-ed25519") == 0) {
+		return KEY_ED25519;
+	}
+	return KEY_UNSPEC;
+}
+
+char* get_ssh2_hostkey_type_name(ssh_keytype type)
+{
+	const struct ssh2_host_key_t *ptr = ssh2_host_key;
+
+	while (ptr->name != NULL) {
+		if (type == ptr->type) {
+			return ptr->name;
+		}
+		ptr++;
+	}
+
+	// not found.
+	return "ssh-unknown";
+}
+
+char *get_ssh2_hostkey_type_name_from_key(Key *key)
+{
+	return get_ssh2_hostkey_type_name(key->type);
+}
+
+char* get_digest_algorithm_name(digest_algorithm id)
+{
+	const struct ssh_digest_t *ptr = ssh_digests;
+
+	while (ptr->name != NULL) {
+		if (id == ptr->id) {
+			return ptr->name;
+		}
+		ptr++;
+	}
+
+	// not found.
+	return "unknown";
+}
+
+void normalize_host_key_order(char *buf)
+{
+	static char default_strings[] = {
+		KEY_ECDSA256,
+		KEY_ECDSA384,
+		KEY_ECDSA521,
+		KEY_ED25519,
+		KEY_RSA,
+		KEY_DSA,
+		KEY_NONE,
+	};
+
+	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
+}
+
+ssh_keytype choose_SSH2_host_key_algorithm(char *server_proposal, char *my_proposal)
+{
+	ssh_keytype type = KEY_UNSPEC;
+	char str_keytype[20];
+	const struct ssh2_host_key_t *ptr = ssh2_host_key;
+
+	choose_SSH2_proposal(server_proposal, my_proposal, str_keytype, sizeof(str_keytype));
+
+	while (ptr->name != NULL) {
+		if (strcmp(ptr->name, str_keytype) == 0) {
+			type = ptr->type;
+			break;
+		}
+		ptr++;
+	}
+
+	return (type);
+}
+
+// Host Key\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B
+// (2011.2.28 yutaka)
+void SSH2_update_host_key_myproposal(PTInstVar pvar)
+{
+	static char buf[256]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
+	int index;
+	int len, i;
+
+	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
+	if (pvar->socket != INVALID_SOCKET) {
+		return;
+	}
+
+	buf[0] = '\0';
+	for (i = 0 ; pvar->settings.HostKeyOrder[i] != 0 ; i++) {
+		index = pvar->settings.HostKeyOrder[i] - '0';
+		if (index == KEY_NONE) // disabled line
+			break;
+		strncat_s(buf, sizeof(buf), get_ssh2_hostkey_type_name(index), _TRUNCATE);
+		strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
+	}
+	len = strlen(buf);
+	if (len > 0)
+		buf[len - 1] = '\0';  // get rid of comma
+	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = buf; 
+}

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,85 @@
+/*
+ * (C) 2021- TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef HOSTKEY_H
+#define HOSTKEY_H
+
+typedef struct Key Key;
+
+typedef enum {
+	KEY_NONE,
+	KEY_RSA1,
+	KEY_RSA,
+	KEY_DSA,
+	KEY_ECDSA256,
+	KEY_ECDSA384,
+	KEY_ECDSA521,
+	KEY_ED25519,
+	KEY_UNSPEC,
+	KEY_MAX = KEY_UNSPEC,
+} ssh_keytype;
+#define isFixedLengthKey(type)	((type) >= KEY_DSA && (type) <= KEY_ED25519)
+
+// fingerprint\x82̎\xED\x95\xCA
+typedef enum {
+	SSH_FP_DEFAULT = 0,
+	SSH_FP_HEX,
+	SSH_FP_BASE64,
+	SSH_FP_BUBBLEBABBLE,
+	SSH_FP_RANDOMART
+} fp_rep;
+
+/*
+enum fp_type {
+	SSH_FP_MD5,
+	SSH_FP_SHA1,
+	SSH_FP_SHA256
+};
+*/
+
+typedef enum {
+	SSH_DIGEST_MD5,
+	SSH_DIGEST_RIPEMD160,
+	SSH_DIGEST_SHA1,
+	SSH_DIGEST_SHA256,
+	SSH_DIGEST_SHA384,
+	SSH_DIGEST_SHA512,
+	SSH_DIGEST_MAX,
+} digest_algorithm;
+
+
+ssh_keytype get_hostkey_type_from_name(char *name);
+char* get_ssh2_hostkey_type_name(ssh_keytype type);
+char *get_ssh2_hostkey_type_name_from_key(Key *key);
+char* get_digest_algorithm_name(digest_algorithm id);
+
+void normalize_host_key_order(char *buf);
+ssh_keytype choose_SSH2_host_key_algorithm(char *server_proposal, char *my_proposal);
+void SSH2_update_host_key_myproposal(PTInstVar pvar);
+
+#endif /* SSHCMAC_H */

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/hosts.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/hosts.c	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/hosts.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -485,7 +485,7 @@
 			}
 			index += (p - cp);  // setup index
 			*p = '\0';
-			key_type = get_keytype_from_name(cp);
+			key_type = get_hostkey_type_from_name(cp);
 			*p = ' ';
 
 			index += eat_spaces(data + index);  // update index
@@ -763,7 +763,7 @@
 			}
 			index += (p - cp);  // setup index
 			*p = '\0';
-			ktype = get_keytype_from_name(cp);
+			ktype = get_hostkey_type_from_name(cp);
 			*p = ' ';
 
 			index += eat_spaces(data + index);  // update index
@@ -1117,13 +1117,13 @@
 			if (pvar->ssh_state.tcpport == 22) {
 				_snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
 				            pvar->hosts_state.prefetched_hostname, 
-				            get_sshname_from_key(key),
+				            get_ssh2_hostkey_type_name_from_key(key),
 				            uu);
 			} else {
 				_snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
 				            pvar->hosts_state.prefetched_hostname,
 				            pvar->ssh_state.tcpport,
-				            get_sshname_from_key(key),
+				            get_ssh2_hostkey_type_name_from_key(key),
 				            uu);
 			}
 		}
@@ -1213,7 +1213,7 @@
 			if (tcpport == 22) {
 				_snprintf_s(result, msize, _TRUNCATE, "%s %s %s\r\n",
 					hostname,
-					get_sshname_from_key(key),
+					get_ssh2_hostkey_type_name_from_key(key),
 					uu);
 			}
 			else {
@@ -1220,7 +1220,7 @@
 				_snprintf_s(result, msize, _TRUNCATE, "[%s]:%d %s %s\r\n",
 					hostname,
 					tcpport,
-					get_sshname_from_key(key),
+					get_ssh2_hostkey_type_name_from_key(key),
 					uu);
 			}
 		}

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.c	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -29,8 +29,140 @@
 #include "ttxssh.h"
 #include "kex.h"
 
+
+char *myproposal[PROPOSAL_MAX] = {
+	KEX_DEFAULT_KEX,
+	KEX_DEFAULT_PK_ALG,
+	KEX_DEFAULT_ENCRYPT,
+	KEX_DEFAULT_ENCRYPT,
+	KEX_DEFAULT_MAC,
+	KEX_DEFAULT_MAC,
+	KEX_DEFAULT_COMP,
+	KEX_DEFAULT_COMP,
+	KEX_DEFAULT_LANG,
+	KEX_DEFAULT_LANG,
+};
+
+struct ssh2_kex_algorithm_t {
+	kex_algorithm kextype;
+	char *name;
+	const EVP_MD *(*evp_md)(void);
+};
+
+static const struct ssh2_kex_algorithm_t ssh2_kex_algorithms[] = {
+	{KEX_DH_GRP1_SHA1,  "diffie-hellman-group1-sha1",           EVP_sha1},   // RFC4253
+	{KEX_DH_GRP14_SHA1, "diffie-hellman-group14-sha1",          EVP_sha1},   // RFC4253
+	{KEX_DH_GEX_SHA1,   "diffie-hellman-group-exchange-sha1",   EVP_sha1},   // RFC4419
+	{KEX_DH_GEX_SHA256, "diffie-hellman-group-exchange-sha256", EVP_sha256}, // RFC4419
+	{KEX_ECDH_SHA2_256, "ecdh-sha2-nistp256",                   EVP_sha256}, // RFC5656
+	{KEX_ECDH_SHA2_384, "ecdh-sha2-nistp384",                   EVP_sha384}, // RFC5656
+	{KEX_ECDH_SHA2_521, "ecdh-sha2-nistp521",                   EVP_sha512}, // RFC5656
+	{KEX_DH_GRP14_SHA256, "diffie-hellman-group14-sha256",      EVP_sha256}, // RFC8268
+	{KEX_DH_GRP16_SHA512, "diffie-hellman-group16-sha512",      EVP_sha512}, // RFC8268
+	{KEX_DH_GRP18_SHA512, "diffie-hellman-group18-sha512",      EVP_sha512}, // RFC8268
+	{KEX_DH_NONE      , NULL,                                   NULL},
+};
+
+
 extern SSHKeys current_keys[MODE_MAX];
 
+
+char* get_kex_algorithm_name(kex_algorithm kextype)
+{
+	const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
+
+	while (ptr->name != NULL) {
+		if (kextype == ptr->kextype) {
+			return ptr->name;
+		}
+		ptr++;
+	}
+
+	// not found.
+	return "unknown";
+}
+
+const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype)
+{
+	const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
+
+	while (ptr->name != NULL) {
+		if (kextype == ptr->kextype) {
+			return ptr->evp_md();
+		}
+		ptr++;
+	}
+
+	// not found.
+	return EVP_md_null();
+}
+
+void normalize_kex_order(char *buf)
+{
+	static char default_strings[] = {
+		KEX_ECDH_SHA2_256,
+		KEX_ECDH_SHA2_384,
+		KEX_ECDH_SHA2_521,
+		KEX_DH_GRP18_SHA512,
+		KEX_DH_GRP16_SHA512,
+		KEX_DH_GRP14_SHA256,
+		KEX_DH_GEX_SHA256,
+		KEX_DH_GEX_SHA1,
+		KEX_DH_GRP14_SHA1,
+		KEX_DH_GRP1_SHA1,
+		KEX_DH_NONE,
+	};
+
+	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
+}
+
+kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal)
+{
+	kex_algorithm type = KEX_DH_UNKNOWN;
+	char str_kextype[40];
+	const struct ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
+
+	choose_SSH2_proposal(server_proposal, my_proposal, str_kextype, sizeof(str_kextype));
+
+	while (ptr->name != NULL) {
+		if (strcmp(ptr->name, str_kextype) == 0) {
+			type = ptr->kextype;
+			break;
+		}
+		ptr++;
+	}
+
+	return (type);
+}
+
+// KEX\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B
+// (2011.2.28 yutaka)
+void SSH2_update_kex_myproposal(PTInstVar pvar)
+{
+	static char buf[512]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
+	int index;
+	int len, i;
+
+	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
+	if (pvar->socket != INVALID_SOCKET) {
+		return;
+	}
+
+	buf[0] = '\0';
+	for (i = 0 ; pvar->settings.KexOrder[i] != 0 ; i++) {
+		index = pvar->settings.KexOrder[i] - '0';
+		if (index == KEX_DH_NONE) // disabled line
+			break;
+		strncat_s(buf, sizeof(buf), get_kex_algorithm_name(index), _TRUNCATE);
+		strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
+	}
+	len = strlen(buf);
+	if (len > 0)
+		buf[len - 1] = '\0';  // get rid of comma
+	myproposal[PROPOSAL_KEX_ALGS] = buf; 
+}
+
+
 static DH *dh_new_group_asc(const char *gen, const char *modulus)
 {
 	DH *dh = NULL;

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.h	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/kex.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -26,8 +26,59 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
+#ifndef KEX_H
+#define KEX_H
+
 #include "ttxssh.h"
 
+// \x83N\x83\x89\x83C\x83A\x83\x93\x83g\x82\xA9\x82\xE7\x83T\x81[\x83o\x82ւ̒\xF1\x88Ď\x96\x8D\x80
+enum kex_init_proposals {
+	PROPOSAL_KEX_ALGS,
+	PROPOSAL_SERVER_HOST_KEY_ALGS,
+	PROPOSAL_ENC_ALGS_CTOS,
+	PROPOSAL_ENC_ALGS_STOC,
+	PROPOSAL_MAC_ALGS_CTOS,
+	PROPOSAL_MAC_ALGS_STOC,
+	PROPOSAL_COMP_ALGS_CTOS,
+	PROPOSAL_COMP_ALGS_STOC,
+	PROPOSAL_LANG_CTOS,
+	PROPOSAL_LANG_STOC,
+	PROPOSAL_MAX
+};
+
+#define KEX_DEFAULT_KEX     ""
+#define KEX_DEFAULT_PK_ALG  ""
+#define KEX_DEFAULT_ENCRYPT ""
+#define KEX_DEFAULT_MAC     ""
+#define KEX_DEFAULT_COMP    ""
+#define KEX_DEFAULT_LANG    ""
+
+extern char *myproposal[PROPOSAL_MAX];
+
+typedef enum {
+	KEX_DH_NONE,       /* disabled line */
+	KEX_DH_GRP1_SHA1,
+	KEX_DH_GRP14_SHA1,
+	KEX_DH_GEX_SHA1,
+	KEX_DH_GEX_SHA256,
+	KEX_ECDH_SHA2_256,
+	KEX_ECDH_SHA2_384,
+	KEX_ECDH_SHA2_521,
+	KEX_DH_GRP14_SHA256,
+	KEX_DH_GRP16_SHA512,
+	KEX_DH_GRP18_SHA512,
+	KEX_DH_UNKNOWN,
+	KEX_DH_MAX = KEX_DH_UNKNOWN,
+} kex_algorithm;
+
+char* get_kex_algorithm_name(kex_algorithm kextype);
+const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype);
+
+void normalize_kex_order(char *buf);
+kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal);
+void SSH2_update_kex_myproposal(PTInstVar pvar);
+
+
 // SSH_MSG_KEY_DH_GEX_REQUEST \x82ł\xCC min, n, max \x82\xAA\x82Ƃ蓾\x82\xE9\x94͈͂̏\xE3\x8C\xC0/\x89\xBA\x8C\xC0 (RFC 4419)
 #define GEX_GRP_LIMIT_MIN   1024
 #define GEX_GRP_LIMIT_MAX   8192
@@ -85,3 +136,5 @@
 int dh_pub_is_valid(DH *dh, BIGNUM *dh_pub);
 void kex_derive_keys(PTInstVar pvar, int need, u_char *hash, BIGNUM *shared_secret,
                      char *session_id, int session_id_len);
+
+#endif				/* KEX_H */

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -392,7 +392,7 @@
 
 	len = get_uint32_MSBfirst(ptr);
 	ptr += 4;
-	if (strncmp(get_ssh_keytype_name(keytype), ptr, len) != 0) {
+	if (strncmp(get_ssh2_hostkey_type_name(keytype), ptr, len) != 0) {
 		ret = -3;
 		goto error;
 	}
@@ -448,7 +448,7 @@
 }
 
 static int ssh_ed25519_verify(Key *key, unsigned char *signature, unsigned int signaturelen, 
-							  unsigned char *data, unsigned int datalen)
+                              unsigned char *data, unsigned int datalen)
 {
 	buffer_t *b;
 	char *ktype = NULL;
@@ -979,7 +979,7 @@
 //
 // fingerprint\x81i\x8Ew\x96\xE4\x81F\x83z\x83X\x83g\x8C\xF6\x8AJ\x8C\xAE\x82̃n\x83b\x83V\x83\x85\x81j\x82𐶐\xAC\x82\xB7\x82\xE9
 //
-char *key_fingerprint(Key *key, enum fp_rep dgst_rep, digest_algorithm dgst_alg)
+char *key_fingerprint(Key *key, fp_rep dgst_rep, digest_algorithm dgst_alg)
 {
 	char *retval = NULL, *alg;
 	unsigned char *dgst_raw;
@@ -1240,42 +1240,6 @@
 	}
 }
 
-//
-// \x83L\x81[\x82\xA9\x82當\x8E\x9A\x97\xF1\x82\xF0\x95ԋp\x82\xB7\x82\xE9
-//
-char *get_sshname_from_key(Key *key)
-{
-	return get_ssh_keytype_name(key->type);
-}
-
-//
-// \x83L\x81[\x95\xB6\x8E\x9A\x97񂩂\xE7\x8E\xED\x95ʂ𔻒肷\x82\xE9
-//
-ssh_keytype get_keytype_from_name(char *name)
-{
-	if (strcmp(name, "rsa1") == 0) {
-		return KEY_RSA1;
-	} else if (strcmp(name, "rsa") == 0) {
-		return KEY_RSA;
-	} else if (strcmp(name, "dsa") == 0) {
-		return KEY_DSA;
-	} else if (strcmp(name, "ssh-rsa") == 0) {
-		return KEY_RSA;
-	} else if (strcmp(name, "ssh-dss") == 0) {
-		return KEY_DSA;
-	} else if (strcmp(name, "ecdsa-sha2-nistp256") == 0) {
-		return KEY_ECDSA256;
-	} else if (strcmp(name, "ecdsa-sha2-nistp384") == 0) {
-		return KEY_ECDSA384;
-	} else if (strcmp(name, "ecdsa-sha2-nistp521") == 0) {
-		return KEY_ECDSA521;
-	} else if (strcmp(name, "ssh-ed25519") == 0) {
-		return KEY_ED25519;
-	}
-	return KEY_UNSPEC;
-}
-
-
 ssh_keytype key_curve_name_to_keytype(char *name)
 {
 	if (strcmp(name, "nistp256") == 0) {
@@ -1318,7 +1282,7 @@
 	BIGNUM *p, *q, *g, *pub_key;
 
 	b = buffer_init();
-	sshname = get_sshname_from_key(key);
+	sshname = get_ssh2_hostkey_type_name_from_key(key);
 
 	switch (key->type) {
 	case KEY_RSA:
@@ -1411,7 +1375,7 @@
 	key[keynamelen] = 0;
 	data += keynamelen;
 
-	type = get_keytype_from_name(key);
+	type = get_hostkey_type_from_name(key);
 
 	switch (type) {
 	case KEY_RSA: // RSA key
@@ -1618,7 +1582,7 @@
 
 		}
 
-		s = get_sshname_from_key(keypair);
+		s = get_ssh2_hostkey_type_name_from_key(keypair);
 		buffer_put_string(msg, s, strlen(s));
 		buffer_append_length(msg, sig, slen);
 		len = buffer_len(msg);
@@ -1676,7 +1640,7 @@
 		DSA_SIG_free(sig);
 
 		// setting
-		s = get_sshname_from_key(keypair);
+		s = get_ssh2_hostkey_type_name_from_key(keypair);
 		buffer_put_string(msg, s, strlen(s));
 		buffer_append_length(msg, sigblob, sizeof(sigblob));
 		len = buffer_len(msg);
@@ -1735,7 +1699,7 @@
 		buffer_put_bignum2(buf2, bs);
 		ECDSA_SIG_free(sig);
 
-		s = get_sshname_from_key(keypair);
+		s = get_ssh2_hostkey_type_name_from_key(keypair);
 		buffer_put_string(msg, s, strlen(s));
 		buffer_put_string(msg, buffer_ptr(buf2), buffer_len(buf2));
 		buffer_free(buf2);
@@ -1791,7 +1755,7 @@
 
 	switch (keypair->type) {
 	case KEY_RSA: // RSA
-		s = get_sshname_from_key(keypair);
+		s = get_ssh2_hostkey_type_name_from_key(keypair);
 		RSA_get0_key(keypair->rsa, &n, &e, NULL);
 		buffer_put_string(msg, s, strlen(s));
 		buffer_put_bignum2(msg, e); // \x8C\xF6\x8AJ\x8Ew\x90\x94
@@ -1800,7 +1764,7 @@
 	case KEY_DSA: // DSA
 		DSA_get0_pqg(keypair->dsa, &p, &q, &g);
 		DSA_get0_key(keypair->dsa, &pub_key, NULL);
-		s = get_sshname_from_key(keypair);
+		s = get_ssh2_hostkey_type_name_from_key(keypair);
 		buffer_put_string(msg, s, strlen(s));
 		buffer_put_bignum2(msg, p); // \x91f\x90\x94
 		buffer_put_bignum2(msg, q); // (p-1)\x82̑f\x88\xF6\x90\x94
@@ -1810,7 +1774,7 @@
 	case KEY_ECDSA256: // ECDSA
 	case KEY_ECDSA384:
 	case KEY_ECDSA521:
-		s = get_sshname_from_key(keypair);
+		s = get_ssh2_hostkey_type_name_from_key(keypair);
 		buffer_put_string(msg, s, strlen(s));
 		tmp = curve_keytype_to_name(keypair->type);
 		buffer_put_string(msg, tmp, strlen(tmp));
@@ -1818,7 +1782,7 @@
 		                        EC_KEY_get0_public_key(keypair->ecdsa));
 		break;
 	case KEY_ED25519:
-		s = get_sshname_from_key(keypair);
+		s = get_ssh2_hostkey_type_name_from_key(keypair);
 		buffer_put_cstring(msg, s);
 		buffer_put_string(msg, keypair->ed25519_pk, ED25519_PK_SZ);
 		break;
@@ -1890,7 +1854,7 @@
 	BIGNUM *e, *n, *d, *iqmp, *p, *q;
 	BIGNUM *g, *pub_key, *priv_key;
 	
-	s = get_sshname_from_key(key);
+	s = get_ssh2_hostkey_type_name_from_key(key);
 	buffer_put_cstring(b, s);
 
 	switch (key->type) {
@@ -1978,7 +1942,7 @@
 	type_name = buffer_get_string_msg(blob, NULL);
 	if (type_name == NULL)
 		goto error;
-	type = get_keytype_from_name(type_name);
+	type = get_hostkey_type_from_name(type_name);
 
 	k = key_new_private(type);
 
@@ -2242,7 +2206,8 @@
 		if (index == KEY_NONE) // disabled line
 			break;
 
-		if (strcmp(get_sshname_from_key(key), get_ssh_keytype_name(index)) == 0)
+		if (strcmp(get_ssh2_hostkey_type_name_from_key(key),
+		           get_ssh2_hostkey_type_name(index)) == 0)
 			return 1;
 	}
 
@@ -2314,7 +2279,7 @@
 				fp = key_fingerprint(ctx->keys[i], SSH_FP_BASE64, SSH_DIGEST_SHA256);
 				break;
 			}
-			strncat_s(buf, buf_len, get_sshname_from_key(ctx->keys[i]), _TRUNCATE);
+			strncat_s(buf, buf_len, get_ssh2_hostkey_type_name_from_key(ctx->keys[i]), _TRUNCATE);
 			strncat_s(buf, buf_len, " ", _TRUNCATE);
 			if (fp != NULL) {
 				strncat_s(buf, buf_len, fp, _TRUNCATE);
@@ -2342,7 +2307,7 @@
 				fp = key_fingerprint(ctx->old_keys[i], SSH_FP_BASE64, SSH_DIGEST_SHA256);
 				break;
 			}
-			strncat_s(buf, buf_len, get_sshname_from_key(ctx->old_keys[i]), _TRUNCATE);
+			strncat_s(buf, buf_len, get_ssh2_hostkey_type_name_from_key(ctx->old_keys[i]), _TRUNCATE);
 			strncat_s(buf, buf_len, " ", _TRUNCATE);
 			if (fp != NULL) {
 				strncat_s(buf, buf_len, fp, _TRUNCATE);
@@ -2557,7 +2522,7 @@
 		if (ret != 1) {
 			logprintf(LOG_LEVEL_ERROR,
 				"server gave bad signature for %s key %u",
-				get_sshname_from_key(ctx->keys[i]), i);
+				get_ssh2_hostkey_type_name_from_key(ctx->keys[i]), i);
 			goto error;
 		}
 		ndone++;
@@ -2628,13 +2593,14 @@
 		blob = NULL;
 
 		fp = key_fingerprint(key, SSH_FP_HEX, SSH_DIGEST_MD5);
-		logprintf(LOG_LEVEL_VERBOSE, "Received %s host key %s", get_sshname_from_key(key), fp);
+		logprintf(LOG_LEVEL_VERBOSE, "Received %s host key %s",
+		          get_ssh2_hostkey_type_name_from_key(key), fp);
 		free(fp);
 
 		// \x8B\x96\x89‚\xB3\x82ꂽ\x83z\x83X\x83g\x83L\x81[\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82\xA9\x82\xF0\x83`\x83F\x83b\x83N\x82\xB7\x82\xE9\x81B
 		if (check_hostkey_algorithm(pvar, key) == 0) {
 			logprintf(LOG_LEVEL_VERBOSE, "%s host key is not permitted by ts.HostKeyOrder",
-				get_sshname_from_key(key));
+			          get_ssh2_hostkey_type_name_from_key(key));
 			continue;
 		}
 
@@ -2644,7 +2610,7 @@
 		for (i = 0; i < ctx->nkeys; i++) {
 			if (HOSTS_compare_public_key(key, ctx->keys[i]) == 1) {
 				logprintf(LOG_LEVEL_ERROR, "Received duplicated %s host key",
-					get_sshname_from_key(key));
+				          get_ssh2_hostkey_type_name_from_key(key));
 				goto error;
 			}
 		}

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.h	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/key.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -44,11 +44,9 @@
 BOOL key_copy(Key *dest, Key *src);
 
 char *key_fingerprint_raw(Key *k, digest_algorithm dgst_alg, int *dgst_raw_length);
-char *key_fingerprint(Key *key, enum fp_rep dgst_rep, digest_algorithm dgst_alg);
+char *key_fingerprint(Key *key, fp_rep dgst_rep, digest_algorithm dgst_alg);
 
 const char *ssh_key_type(ssh_keytype type);
-char *get_sshname_from_key(Key *key);
-ssh_keytype get_keytype_from_name(char *name);
 char *curve_keytype_to_name(ssh_keytype type);
 ssh_keytype key_curve_name_to_keytype(char *name);
 
@@ -74,4 +72,4 @@
 
 int update_client_input_hostkeys(PTInstVar pvar, char *dataptr, int datalen);
 
-#endif
+#endif /* __KEY_H_ */

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/keyfiles.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -379,7 +379,7 @@
 	unsigned int len, klen, nkeys, blocksize, keylen, ivlen, slen, rounds;
 	unsigned int check1, check2, m1len, m2len; 
 	int dlen, i;
-	SSH2Cipher *cipher;
+	const struct ssh2cipher *cipher;
 	size_t authlen;
 	EVP_CIPHER_CTX *cipher_ctx = NULL;
 	int ret;
@@ -982,9 +982,9 @@
 
 	macdata = buffer_init();
 
-	len = strlen(get_ssh_keytype_name(result->type));
+	len = strlen(get_ssh2_hostkey_type_name(result->type));
 	buffer_put_int(macdata, len);
-	buffer_append(macdata, get_ssh_keytype_name(result->type), len);
+	buffer_append(macdata, get_ssh2_hostkey_type_name(result->type), len);
 	len = strlen(encname);
 	buffer_put_int(macdata, len);
 	buffer_append(macdata, encname, len);

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,191 @@
+/*
+ * (C) 2021- TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "ttxssh.h"
+#include "mac.h"
+#include "kex.h"
+
+
+struct SSH2Mac {
+	SSH2MacId id;
+	char *name;
+	const EVP_MD *(*evp_md)(void);
+	int truncatebits;
+	int etm;
+};
+
+static const struct SSH2Mac ssh2_macs[] = {
+	{HMAC_SHA1,         "hmac-sha1",                     EVP_sha1,      0,  0}, // RFC4253
+	{HMAC_MD5,          "hmac-md5",                      EVP_md5,       0,  0}, // RFC4253
+	{HMAC_SHA1_96,      "hmac-sha1-96",                  EVP_sha1,      96, 0}, // RFC4253
+	{HMAC_MD5_96,       "hmac-md5-96",                   EVP_md5,       96, 0}, // RFC4253
+	{HMAC_RIPEMD160,    "hmac-****@opens*****",    EVP_ripemd160, 0,  0},
+	{HMAC_SHA2_256,     "hmac-sha2-256",                 EVP_sha256,    0,  0}, // RFC6668
+//	{HMAC_SHA2_256_96,  "hmac-sha2-256-96",              EVP_sha256,    96, 0}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06
+	{HMAC_SHA2_512,     "hmac-sha2-512",                 EVP_sha512,    0,  0}, // RFC6668
+//	{HMAC_SHA2_512_96,  "hmac-sha2-512-96",              EVP_sha512,    96, 0}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06
+	{HMAC_SHA1_EtM,     "hmac-****@opens*****",     EVP_sha1,      0,  1},
+	{HMAC_MD5_EtM,      "hmac-****@opens*****",      EVP_md5,       0,  1},
+	{HMAC_SHA1_96_EtM,  "hmac-****@opens*****",  EVP_sha1,      96, 1},
+	{HMAC_MD5_96_EtM,   "hmac-****@opens*****",   EVP_md5,       96, 1},
+	{HMAC_RIPEMD160_EtM,"hmac-****@opens*****",EVP_ripemd160, 0,  1},
+	{HMAC_SHA2_256_EtM, "hmac-****@opens*****", EVP_sha256,    0,  1},
+	{HMAC_SHA2_512_EtM, "hmac-****@opens*****", EVP_sha512,    0,  1},
+	{HMAC_IMPLICIT,     "<implicit>",                    EVP_md_null,   0,  0}, // for AEAD cipher
+	{HMAC_NONE,         NULL,                            NULL,          0,  0},
+};
+
+
+char* get_ssh2_mac_name(const struct SSH2Mac *mac)
+{
+	if (mac) {
+		return mac->name;
+	}
+	else {
+		return "unknown";
+	}
+}
+
+char* get_ssh2_mac_name_by_id(const SSH2MacId id)
+{
+	return get_ssh2_mac_name(get_ssh2_mac(id));
+}
+
+const EVP_MD* get_ssh2_mac_EVP_MD(const struct SSH2Mac *mac)
+{
+	if (mac) {
+		return mac->evp_md();
+	}
+	else {
+		return EVP_md_null();
+	}
+}
+
+const struct SSH2Mac *get_ssh2_mac(SSH2MacId id)
+{
+	const struct SSH2Mac *ptr = ssh2_macs;
+
+	while (ptr->name != NULL) {
+		if (ptr->id == id) {
+			return ptr;
+		}
+		ptr++;
+	}
+
+	return NULL;
+}
+
+int get_ssh2_mac_truncatebits(const struct SSH2Mac *mac)
+{
+	if (mac) {
+		return mac->truncatebits;
+	}
+	else {
+		return 0;
+	}
+}
+
+int get_ssh2_mac_etm(const struct SSH2Mac *mac)
+{
+	if (mac) {
+		return mac->etm;
+	}
+	else {
+		return 0;
+	}
+}
+
+void normalize_mac_order(char *buf)
+{
+	static char default_strings[] = {
+		HMAC_SHA2_512_EtM,
+		HMAC_SHA2_256_EtM,
+		HMAC_SHA1_EtM,
+		HMAC_SHA2_512,
+		HMAC_SHA2_256,
+		HMAC_SHA1,
+		HMAC_RIPEMD160_EtM,
+		HMAC_RIPEMD160,
+		HMAC_MD5_EtM,
+		HMAC_MD5,
+		HMAC_NONE,
+		HMAC_SHA1_96_EtM,
+		HMAC_MD5_96_EtM,
+		HMAC_SHA1_96,
+		HMAC_MD5_96,
+		0, // Dummy for HMAC_SHA2_512_96,
+		0, // Dummy for HMAC_SHA2_256_96,
+	};
+
+	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
+}
+
+const struct SSH2Mac *choose_SSH2_mac_algorithm(char *server_proposal, char *my_proposal)
+{
+	char str_hmac[64];
+	const struct SSH2Mac *ptr = ssh2_macs;
+
+	choose_SSH2_proposal(server_proposal, my_proposal, str_hmac, sizeof(str_hmac));
+
+	while (ptr->name != NULL) {
+		if (strcmp(ptr->name, str_hmac) == 0) {
+			return ptr;
+		}
+		ptr++;
+	}
+
+	return (NULL);
+}
+
+// HMAC\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B
+// (2011.2.28 yutaka)
+void SSH2_update_hmac_myproposal(PTInstVar pvar)
+{
+	static char buf[256]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
+	int index;
+	int len, i;
+
+	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
+	if (pvar->socket != INVALID_SOCKET) {
+		return;
+	}
+
+	buf[0] = '\0';
+	for (i = 0 ; pvar->settings.MacOrder[i] != 0 ; i++) {
+		index = pvar->settings.MacOrder[i] - '0';
+		if (index == HMAC_NONE) // disabled line
+			break;
+		strncat_s(buf, sizeof(buf), get_ssh2_mac_name_by_id(index), _TRUNCATE);
+		strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
+	}
+	len = strlen(buf);
+	if (len > 0)
+		buf[len - 1] = '\0';  // get rid of comma
+	myproposal[PROPOSAL_MAC_ALGS_CTOS] = buf; 
+	myproposal[PROPOSAL_MAC_ALGS_STOC] = buf; 
+}

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,69 @@
+/*
+ * (C) 2021- TeraTerm Project
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+ * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
+ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#ifndef SSHMAC_H
+#define SSHMAC_H
+
+#include "ttxssh.h"
+
+struct SSH2Mac;
+
+typedef enum {
+	HMAC_NONE,      /* disabled line */
+	HMAC_SHA1,
+	HMAC_MD5,
+	HMAC_SHA1_96,
+	HMAC_MD5_96,
+	HMAC_RIPEMD160,
+	HMAC_SHA2_256,
+	HMAC_SHA2_256_96,
+	HMAC_SHA2_512,
+	HMAC_SHA2_512_96,
+	HMAC_SHA1_EtM,
+	HMAC_MD5_EtM,
+	HMAC_SHA1_96_EtM,
+	HMAC_MD5_96_EtM,
+	HMAC_RIPEMD160_EtM,
+	HMAC_SHA2_256_EtM,
+	HMAC_SHA2_512_EtM,
+	HMAC_IMPLICIT,
+	HMAC_UNKNOWN,
+	HMAC_MAX = HMAC_UNKNOWN,
+} SSH2MacId;
+
+char* get_ssh2_mac_name(const struct SSH2Mac *mac);
+char* get_ssh2_mac_name_by_id(SSH2MacId id);
+const EVP_MD* get_ssh2_mac_EVP_MD(const struct SSH2Mac *mac);
+const struct SSH2Mac *get_ssh2_mac(SSH2MacId id);
+int get_ssh2_mac_truncatebits(const struct SSH2Mac *mac);
+int get_ssh2_mac_etm(const struct SSH2Mac *mac);
+void normalize_mac_order(char *buf);
+const struct SSH2Mac *choose_SSH2_mac_algorithm(char *server_proposal, char *my_proposal);
+void SSH2_update_hmac_myproposal(PTInstVar pvar);
+
+#endif /* SSHCMAC_H */

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -4339,239 +4339,6 @@
 #define write_buffer_file(buf,len) do_write_buffer_file(buf,len,__FILE__,__LINE__)
 
 
-//
-// general
-//
-
-int get_cipher_block_size(SSH2Cipher *cipher)
-{
-	int blocksize = 0;
-	
-	if (cipher) {
-		blocksize = cipher->block_size;
-	}
-
-	return max(blocksize, 8);
-}
-
-int get_cipher_key_len(SSH2Cipher *cipher)
-{
-	if (cipher) {
-		return cipher->key_len;
-	}
-	else {
-		return 0;
-	}
-}
-
-int get_cipher_discard_len(SSH2Cipher *cipher)
-{
-	if (cipher) {
-		return cipher->discard_len;
-	}
-	else {
-		return 0;
-	}
-}
-
-int get_cipher_iv_len(SSH2Cipher *cipher)
-{
-	if (cipher) {
-		if (cipher->iv_len != 0) {
-			return cipher->iv_len;
-		}
-		else {
-			return cipher->block_size;
-		}
-	}
-	else {
-		return 8; // block_size
-	}
-}
-
-int get_cipher_auth_len(SSH2Cipher *cipher)
-{
-	if (cipher) {
-		return cipher->auth_len;
-	}
-	else {
-		return 0;
-	}
-}
-
-// \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x96\xBC\x82\xA9\x82猟\x8D\x{142DC2}\xE9\x81B
-SSH2Cipher *get_cipher_by_name(char *name)
-{
-	SSH2Cipher *ptr = ssh2_ciphers;
-
-	if (name == NULL || name[0] == '\0')
-		return NULL;
-
-	while (ptr->name != NULL) {
-		if (strcmp(ptr->name, name) == 0) {
-			return ptr;
-		}
-		ptr++;
-	}
-
-	// not found.
-	return NULL;
-}
-
-static char * get_cipher_string(SSH2Cipher *cipher)
-{
-	if (cipher) {
-		return cipher->name;
-	}
-	else {
-		return "unknown";
-	}
-}
-
-const EVP_CIPHER* get_cipher_EVP_CIPHER(SSH2Cipher *cipher)
-{
-	if (cipher) {
-		return cipher->func();
-	}
-	else {
-		return EVP_enc_null();
-	}
-}
-
-char* get_kex_algorithm_name(kex_algorithm kextype)
-{
-	ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
-
-	while (ptr->name != NULL) {
-		if (kextype == ptr->kextype) {
-			return ptr->name;
-		}
-		ptr++;
-	}
-
-	// not found.
-	return "unknown";
-}
-
-const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype)
-{
-	ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
-
-	while (ptr->name != NULL) {
-		if (kextype == ptr->kextype) {
-			return ptr->evp_md();
-		}
-		ptr++;
-	}
-
-	// not found.
-	return EVP_md_null();
-}
-
-SSH2Mac *get_ssh2_mac(SSH2MacId id)
-{
-	SSH2Mac *ptr = ssh2_macs;
-
-	while (ptr->name != NULL) {
-		if (ptr->id == id) {
-			return ptr;
-		}
-		ptr++;
-	}
-
-	return NULL;
-}
-
-char* get_ssh2_mac_name(SSH2Mac *mac)
-{
-	if (mac) {
-		return mac->name;
-	}
-	else {
-		return "unknown";
-	}
-}
-
-char* get_ssh2_mac_name_by_id(SSH2MacId id)
-{
-	return get_ssh2_mac_name(get_ssh2_mac(id));
-}
-
-const EVP_MD* get_ssh2_mac_EVP_MD(SSH2Mac *mac)
-{
-	if (mac) {
-		return mac->evp_md();
-	}
-	else {
-		return EVP_md_null();
-	}
-}
-
-int get_ssh2_mac_truncatebits(SSH2Mac *mac)
-{
-	if (mac) {
-		return mac->truncatebits;
-	}
-	else {
-		return 0;
-	}
-}
-
-int get_ssh2_mac_etm(SSH2Mac *mac)
-{
-	if (mac) {
-		return mac->etm;
-	}
-	else {
-		return 0;
-	}
-}
-
-char* get_ssh2_comp_name(compression_type type)
-{
-	ssh2_comp_t *ptr = ssh2_comps;
-
-	while (ptr->name != NULL) {
-		if (type == ptr->type) {
-			return ptr->name;
-		}
-		ptr++;
-	}
-
-	// not found.
-	return "unknown";
-}
-
-char* get_ssh_keytype_name(ssh_keytype type)
-{
-	ssh2_host_key_t *ptr = ssh2_host_key;
-
-	while (ptr->name != NULL) {
-		if (type == ptr->type) {
-			return ptr->name;
-		}
-		ptr++;
-	}
-
-	// not found.
-	return "ssh-unknown";
-}
-
-char* get_digest_algorithm_name(digest_algorithm id)
-{
-	ssh_digest_t *ptr = ssh_digests;
-
-	while (ptr->name != NULL) {
-		if (id == ptr->id) {
-			return ptr->name;
-		}
-		ptr++;
-	}
-
-	// not found.
-	return "unknown";
-}
-
 static void do_write_buffer_file(void *buf, int len, char *file, int lineno)
 {
 	FILE *fp;
@@ -4599,248 +4366,6 @@
 	buffer_append(msg, buf, len);
 }
 
-// the caller is normalize_cipher_order()
-void SSH2_update_cipher_myproposal(PTInstVar pvar)
-{
-	static char buf[512]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
-	int cipher;
-	int len, i;
-	char *c_str;
-
-	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
-	if (pvar->socket != INVALID_SOCKET) {
-		return;
-	}
-
-	// \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B(2004.11.6 yutaka)
-	buf[0] = '\0';
-	for (i = 0 ; pvar->settings.CipherOrder[i] != 0 ; i++) {
-		cipher = pvar->settings.CipherOrder[i] - '0';
-		if (cipher == 0) // disabled line
-			break;
-		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;
-#ifdef WITH_CAMELLIA_PRIVATE
-			case SSH2_CIPHER_CAMELLIA128_CBC:
-				c_str = "camellia128-cbc,camel****@opens*****,";
-				break;
-			case SSH2_CIPHER_CAMELLIA192_CBC:
-				c_str = "camellia192-cbc,camel****@opens*****,";
-				break;
-			case SSH2_CIPHER_CAMELLIA256_CBC:
-				c_str = "camellia256-cbc,camel****@opens*****,";
-				break;
-			case SSH2_CIPHER_CAMELLIA128_CTR:
-				c_str = "camellia128-ctr,camel****@opens*****,";
-				break;
-			case SSH2_CIPHER_CAMELLIA192_CTR:
-				c_str = "camellia192-ctr,camel****@opens*****,";
-				break;
-			case SSH2_CIPHER_CAMELLIA256_CTR:
-				c_str = "camellia256-ctr,camel****@opens*****,";
-				break;
-#endif // WITH_CAMELLIA_PRIVATE
-			case SSH2_CIPHER_CAMELLIA128_CBC:
-				c_str = "camellia128-cbc,";
-				break;
-			case SSH2_CIPHER_CAMELLIA192_CBC:
-				c_str = "camellia192-cbc,";
-				break;
-			case SSH2_CIPHER_CAMELLIA256_CBC:
-				c_str = "camellia256-cbc,";
-				break;
-			case SSH2_CIPHER_CAMELLIA128_CTR:
-				c_str = "camellia128-ctr,";
-				break;
-			case SSH2_CIPHER_CAMELLIA192_CTR:
-				c_str = "camellia192-ctr,";
-				break;
-			case SSH2_CIPHER_CAMELLIA256_CTR:
-				c_str = "camellia256-ctr,";
-				break;
-			case SSH2_CIPHER_AES128_GCM:
-				c_str = "aes12****@opens*****,";
-				break;
-			case SSH2_CIPHER_AES256_GCM:
-				c_str = "aes25****@opens*****,";
-				break;
-			default:
-				continue;
-		}
-		strncat_s(buf, sizeof(buf), c_str, _TRUNCATE);
-	}
-	len = strlen(buf);
-	if (len > 0)
-		buf[len - 1] = '\0';  // get rid of comma
-	myproposal[PROPOSAL_ENC_ALGS_CTOS] = buf;  // Client To Server
-	myproposal[PROPOSAL_ENC_ALGS_STOC] = buf;  // Server To Client
-}
-
-
-void SSH2_update_compression_myproposal(PTInstVar pvar)
-{
-	static char buf[128]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
-	int index;
-	int len, i;
-
-	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
-	if (pvar->socket != INVALID_SOCKET) {
-		return;
-	}
-
-	// \x88\xB3\x8Fk\x83\x8C\x83x\x83\x8B\x82ɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B(2005.7.9 yutaka)
-	buf[0] = '\0';
-	for (i = 0 ; pvar->settings.CompOrder[i] != 0 ; i++) {
-		index = pvar->settings.CompOrder[i] - '0';
-		if (index == COMP_NONE) // disabled line
-			break;
-		strncat_s(buf, sizeof(buf), get_ssh2_comp_name(index), _TRUNCATE);
-		strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
-	}
-	len = strlen(buf);
-	if (len > 0)
-		buf[len - 1] = '\0';  // get rid of comma
-
-	// \x88\xB3\x8Fk\x8Ew\x92肪\x82Ȃ\xA2\x8Fꍇ\x82́A\x88\xB3\x8Fk\x83\x8C\x83x\x83\x8B\x82𖳏\xF0\x8C\x8F\x82Ƀ[\x83\x8D\x82ɂ\xB7\x82\xE9\x81B
-	if (buf[0] == '\0') {
-		pvar->settings.CompressionLevel = 0;
-	}
-
-	if (pvar->settings.CompressionLevel == 0) {
-		_snprintf_s(buf, sizeof(buf), _TRUNCATE, get_ssh2_comp_name(COMP_NOCOMP));
-	}
-	if (buf[0] != '\0') {
-		myproposal[PROPOSAL_COMP_ALGS_CTOS] = buf;  // Client To Server
-		myproposal[PROPOSAL_COMP_ALGS_STOC] = buf;  // Server To Client
-	}
-}
-
-// KEX\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B
-// (2011.2.28 yutaka)
-void SSH2_update_kex_myproposal(PTInstVar pvar)
-{
-	static char buf[512]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
-	int index;
-	int len, i;
-
-	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
-	if (pvar->socket != INVALID_SOCKET) {
-		return;
-	}
-
-	buf[0] = '\0';
-	for (i = 0 ; pvar->settings.KexOrder[i] != 0 ; i++) {
-		index = pvar->settings.KexOrder[i] - '0';
-		if (index == KEX_DH_NONE) // disabled line
-			break;
-		strncat_s(buf, sizeof(buf), get_kex_algorithm_name(index), _TRUNCATE);
-		strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
-	}
-	len = strlen(buf);
-	if (len > 0)
-		buf[len - 1] = '\0';  // get rid of comma
-	myproposal[PROPOSAL_KEX_ALGS] = buf; 
-}
-
-// Host Key\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B
-// (2011.2.28 yutaka)
-void SSH2_update_host_key_myproposal(PTInstVar pvar)
-{
-	static char buf[256]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
-	int index;
-	int len, i;
-
-	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
-	if (pvar->socket != INVALID_SOCKET) {
-		return;
-	}
-
-	buf[0] = '\0';
-	for (i = 0 ; pvar->settings.HostKeyOrder[i] != 0 ; i++) {
-		index = pvar->settings.HostKeyOrder[i] - '0';
-		if (index == KEY_NONE) // disabled line
-			break;
-		strncat_s(buf, sizeof(buf), get_ssh_keytype_name(index), _TRUNCATE);
-		strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
-	}
-	len = strlen(buf);
-	if (len > 0)
-		buf[len - 1] = '\0';  // get rid of comma
-	myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS] = buf; 
-}
-
-// HMAC\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x97D\x90揇\x88ʂɉ\x9E\x82\xB6\x82āAmyproposal[]\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9\x81B
-// (2011.2.28 yutaka)
-void SSH2_update_hmac_myproposal(PTInstVar pvar)
-{
-	static char buf[256]; // TODO: malloc()\x82ɂ\xB7\x82ׂ\xAB
-	int index;
-	int len, i;
-
-	// \x92ʐM\x92\x86\x82ɂ͌Ă΂\xEA\x82Ȃ\xA2\x82͂\xB8\x82\xBE\x82\xAA\x81A\x94O\x82̂\xBD\x82߁B(2006.6.26 maya)
-	if (pvar->socket != INVALID_SOCKET) {
-		return;
-	}
-
-	buf[0] = '\0';
-	for (i = 0 ; pvar->settings.MacOrder[i] != 0 ; i++) {
-		index = pvar->settings.MacOrder[i] - '0';
-		if (index == HMAC_NONE) // disabled line
-			break;
-		strncat_s(buf, sizeof(buf), get_ssh2_mac_name_by_id(index), _TRUNCATE);
-		strncat_s(buf, sizeof(buf), ",", _TRUNCATE);
-	}
-	len = strlen(buf);
-	if (len > 0)
-		buf[len - 1] = '\0';  // get rid of comma
-	myproposal[PROPOSAL_MAC_ALGS_CTOS] = buf; 
-	myproposal[PROPOSAL_MAC_ALGS_STOC] = buf; 
-}
-
 // \x83N\x83\x89\x83C\x83A\x83\x93\x83g\x82\xA9\x82\xE7\x83T\x81[\x83o\x82ւ̃L\x81[\x8C\xF0\x8A\xB7\x8AJ\x8En\x97v\x8B\x81
 void SSH2_send_kexinit(PTInstVar pvar)
 {
@@ -4920,11 +4445,99 @@
 }
 
 
-static void choose_SSH2_proposal(char *server_proposal,
-                                 char *my_proposal,
-                                 char *dest,
-                                 int dest_len)
+void normalize_generic_order(char *buf, char default_strings[], int default_strings_len)
 {
+	char listed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1];
+	char allowed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1];
+	int i, j, k=-1;
+
+	memset(listed, 0, sizeof(listed));
+	memset(allowed, 0, sizeof(allowed));
+
+	// \x8B\x96\x89‚\xB3\x82\xEA\x82Ă\xA2\x82镶\x8E\x9A\x82̃\x8A\x83X\x83g\x82\xF0\x8D\xEC\x82\xE9\x81B
+	for (i = 0; i < default_strings_len ; i++) {
+		allowed[default_strings[i]] = 1;
+	}
+
+	// \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82𑖍\xB8\x82\xB5\x81A\x8B\x96\x89‚\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x95\xB6\x8E\x9A\x81A\x8Fd\x95\xA1\x82\xB7\x82镶\x8E\x9A\x82͍폜\x82\xB7\x82\xE9\x81B
+	// 
+	// ex. (i=5 \x82̕\xB6\x8E\x9A\x82\xF0\x8D폜\x82\xB7\x82\xE9)
+	// i=012345
+	//   >:=9<87;A@?B3026(\0)
+	//         i+1
+	//         <------------>
+	//       \x81\xAB
+	//   >:=9<7;A@?B3026(\0)
+	//         
+	for (i = 0; buf[i] != 0; i++) {
+		int num = buf[i] - '0';
+
+		if (num < 0 || num > default_strings_len
+			|| !allowed[num]
+			|| listed[num]) {
+			memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1);
+			i--;
+		} else {
+			listed[num] = 1;
+		}
+
+		// disabled line\x82\xAA\x82\xA0\x82\xEA\x82΁A\x88ʒu\x82\xF0\x8Ao\x82\xA6\x82Ă\xA8\x82\xAD\x81B
+		if (num == 0) {
+			k = i;
+		}
+	}
+
+	// \x8Ew\x92肳\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x95\xB6\x8E\x9A\x82\xAA\x82\xA0\x82\xEA\x82΁Adisabled line\x82̒\xBC\x91O\x82ɑ}\x93\xFC\x82\xB7\x82\xE9\x81B
+	// 
+	// ex. (Z\x82\xF0\x91}\x93\xFC\x82\xB7\x82\xE9)
+	//                k
+	//   >:=9<87;A@?B3026(\0)
+	//                 k+1
+	//                 <---->
+	//       \x81\xAB       k
+	//   >:=9<87;A@?B30026(\0)
+	//       \x81\xAB        k
+	//   >:=9<87;A@?B3Z026(\0)
+	//       
+	for (j = 0; j < default_strings_len && default_strings[j] != 0; j++) {
+		int num = default_strings[j];
+
+		if (!listed[num] && k >= 0) {
+			int copylen = strlen(buf + k + 1) + 1;
+
+			memmove(buf + k + 1, buf + k, copylen);
+			buf[k + 1 + copylen] = '\0';   // \x8FI\x92[\x82\xF0\x96Y\x82ꂸ\x82ɕt\x82\xAF\x82\xE9\x81B
+			buf[k] = num + '0';
+			k++;
+			i++;
+		}
+	}
+	if (k < 0) {
+		j = 0;
+	}
+	else {
+		j++;
+	}
+
+	// disabled line\x82\xAA\x91\xB6\x8D݂\xB5\x82Ȃ\xA2\x8Fꍇ\x82́A\x82\xBB\x82̂܂ܖ\x96\x94\xF6\x82ɒlj\xC1\x82\xB7\x82\xE9\x81B
+	for (; j < default_strings_len ; j++) {
+		int num = default_strings[j];
+
+		if (!listed[num]) {
+			buf[i] = num + '0';
+			listed[num] = 1;
+			i++;
+		}
+	}
+
+	buf[i] = 0;
+}
+
+void choose_SSH2_proposal(char *server_proposal,
+                          char *my_proposal,
+                          char *dest,
+                          int dest_len)
+{
 	char tmp_cli[1024], *ptr_cli, *ctc_cli;
 	char tmp_svr[1024], *ptr_svr, *ctc_svr;
 
@@ -4952,79 +4565,6 @@
 	}
 }
 
-static kex_algorithm choose_SSH2_kex_algorithm(char *server_proposal, char *my_proposal)
-{
-	kex_algorithm type = KEX_DH_UNKNOWN;
-	char str_kextype[40];
-	ssh2_kex_algorithm_t *ptr = ssh2_kex_algorithms;
-
-	choose_SSH2_proposal(server_proposal, my_proposal, str_kextype, sizeof(str_kextype));
-
-	while (ptr->name != NULL) {
-		if (strcmp(ptr->name, str_kextype) == 0) {
-			type = ptr->kextype;
-			break;
-		}
-		ptr++;
-	}
-
-	return (type);
-}
-
-static SSH2Cipher *choose_SSH2_cipher_algorithm(char *server_proposal, char *my_proposal)
-{
-	char str_cipher[32];
-	SSH2Cipher *ptr = ssh2_ciphers;
-
-	choose_SSH2_proposal(server_proposal, my_proposal, str_cipher, sizeof(str_cipher));
-	return get_cipher_by_name(str_cipher);
-}
-
-
-static SSH2Mac *choose_SSH2_mac_algorithm(char *server_proposal, char *my_proposal)
-{
-	char str_hmac[64];
-	SSH2Mac *ptr = ssh2_macs;
-
-	choose_SSH2_proposal(server_proposal, my_proposal, str_hmac, sizeof(str_hmac));
-
-	while (ptr->name != NULL) {
-		if (strcmp(ptr->name, str_hmac) == 0) {
-			return ptr;
-		}
-		ptr++;
-	}
-
-	return (NULL);
-}
-
-
-static compression_type choose_SSH2_compression_algorithm(char *server_proposal, char *my_proposal)
-{
-	compression_type type = COMP_UNKNOWN;
-	char str_comp[20];
-	ssh2_comp_t *ptr = ssh2_comps;
-
-	// OpenSSH 4.3\x82ł͒x\x89\x84\x83p\x83P\x83b\x83g\x88\xB3\x8Fk("zlib****@opens*****")\x82\xAA\x90V\x8BK\x92lj\xC1\x82\xB3\x82\xEA\x82Ă\xA2\x82邽\x82߁A
-	// \x83}\x83b\x83`\x82\xB5\x82Ȃ\xA2\x82悤\x82ɏC\x90\xB3\x82\xB5\x82\xBD\x81B
-	// \x8C\xBBTera Term\x82ł͒x\x89\x84\x83p\x83P\x83b\x83g\x88\xB3\x8Fk\x82͏\xAB\x97\x88\x93I\x82ɃT\x83|\x81[\x83g\x82\xB7\x82\xE9\x97\\x92\xE8\x81B
-	// (2006.6.14 yutaka)
-	// \x92x\x89\x84\x83p\x83P\x83b\x83g\x88\xB3\x8Fk\x82ɑΉ\x9E\x81B
-	// (2006.6.23 maya)
-
-	choose_SSH2_proposal(server_proposal, my_proposal, str_comp, sizeof(str_comp));
-
-	while (ptr->name != NULL) {
-		if (strcmp(ptr->name, str_comp) == 0) {
-			type = ptr->type;
-			break;
-		}
-		ptr++;
-	}
-
-	return (type);
-}
-
 // \x88Í\x86\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̃L\x81[\x83T\x83C\x83Y\x81A\x83u\x83\x8D\x83b\x83N\x83T\x83C\x83Y\x81AMAC\x83T\x83C\x83Y\x82̂\xA4\x82\xBF\x8Dő\xE5\x92l(we_need)\x82\xF0\x8C\x88\x92肷\x82\xE9\x81B
 static void choose_SSH2_key_maxlength(PTInstVar pvar)
 {
@@ -5031,8 +4571,8 @@
 	int mode, val;
 	unsigned int need = 0;
 	const EVP_MD *md;
-	SSH2Cipher *cipher;
-	SSH2Mac *mac;
+	const struct ssh2cipher *cipher;
+	const struct SSH2Mac *mac;
 
 	for (mode = 0; mode < MODE_MAX; mode++) {
 		cipher = pvar->ciphers[mode];
@@ -5097,7 +4637,6 @@
 	int len, size;
 	char *msg = NULL;
 	char tmp[1024+512];
-	char str_keytype[20];
 
 	logputs(LOG_LEVEL_VERBOSE, "SSH2_MSG_KEXINIT was received.");
 
@@ -5181,15 +4720,7 @@
 
 	logprintf(LOG_LEVEL_VERBOSE, "server proposal: server host key algorithm: %s", buf);
 
-	pvar->hostkey_type = KEY_UNSPEC;
-	choose_SSH2_proposal(buf, myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS], str_keytype, sizeof(str_keytype));
-	if (strlen(str_keytype) == 0) { // not match
-		strncpy_s(tmp, sizeof(tmp), "unknown host KEY type: ", _TRUNCATE);
-		strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE);
-		msg = tmp;
-		goto error;
-	}
-	pvar->hostkey_type = get_keytype_from_name(str_keytype);
+	pvar->hostkey_type = choose_SSH2_host_key_algorithm(buf, myproposal[PROPOSAL_SERVER_HOST_KEY_ALGS]);
 	if (pvar->hostkey_type == KEY_UNSPEC) {
 		strncpy_s(tmp, sizeof(tmp), "unknown host KEY type: ", _TRUNCATE);
 		strncat_s(tmp, sizeof(tmp), buf, _TRUNCATE);
@@ -5255,7 +4786,7 @@
 
 	logprintf(LOG_LEVEL_VERBOSE, "server proposal: MAC algorithm client to server: %s", buf);
 
-	if (pvar->ciphers[MODE_OUT]->auth_len > 0) {
+	if (get_cipher_auth_len(pvar->ciphers[MODE_OUT]) > 0) {
 		logputs(LOG_LEVEL_VERBOSE, "AEAD cipher is selected, ignoring MAC algorithms. (client to server)");
 		pvar->macs[MODE_OUT] = get_ssh2_mac(HMAC_IMPLICIT);
 	}
@@ -5283,7 +4814,7 @@
 
 	logprintf(LOG_LEVEL_VERBOSE, "server proposal: MAC algorithm server to client: %s", buf);
 
-	if (pvar->ciphers[MODE_IN]->auth_len > 0) {
+	if (get_cipher_auth_len(pvar->ciphers[MODE_IN]) > 0) {
 		logputs(LOG_LEVEL_VERBOSE, "AEAD cipher is selected, ignoring MAC algorithms. (server to client)");
 		pvar->macs[MODE_IN] = get_ssh2_mac(HMAC_IMPLICIT);
 	}
@@ -5400,7 +4931,7 @@
 		get_kex_algorithm_name(pvar->kex_type));
 
 	logprintf(LOG_LEVEL_VERBOSE, "server host key algorithm: %s",
-		get_ssh_keytype_name(pvar->hostkey_type));
+		get_ssh2_hostkey_type_name(pvar->hostkey_type));
 
 	logprintf(LOG_LEVEL_VERBOSE, "encryption algorithm client to server: %s",
 		get_cipher_string(pvar->ciphers[MODE_OUT]));
@@ -6028,7 +5559,7 @@
 	if (hostkey->type != pvar->hostkey_type) {  // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar
 		_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE,
 		            "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_dh_kex_reply",
-		            get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type));
+		            get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type));
 		emsg = emsg_tmp;
 		goto error;
 	}
@@ -6130,7 +5661,7 @@
 	if (hostkey->type != pvar->hostkey_type) {  // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar
 		_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE,
 		            "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_dh_kex_reply",
-		            get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type));
+		            get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type));
 		emsg = emsg_tmp;
 		goto error;
 	}
@@ -6293,7 +5824,7 @@
 	if (hostkey->type != pvar->hostkey_type) {  // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar
 		_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE,
 		            "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_dh_gex_reply",
-		            get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type));
+		            get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type));
 		emsg = emsg_tmp;
 		goto error;
 	}
@@ -6402,7 +5933,7 @@
 	if (hostkey->type != pvar->hostkey_type) {  // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar
 		_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE,
 		            "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_dh_gex_reply",
-		            get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type));
+		            get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type));
 		emsg = emsg_tmp;
 		goto error;
 	}
@@ -6566,7 +6097,7 @@
 	if (hostkey->type != pvar->hostkey_type) {  // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar
 		_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE,
 		            "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_ecdh_kex_reply",
-		            get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type));
+		            get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type));
 		emsg = emsg_tmp;
 		goto error;
 	}
@@ -6674,7 +6205,7 @@
 	if (hostkey->type != pvar->hostkey_type) {  // \x83z\x83X\x83g\x83L\x81[\x82̎\xED\x95ʔ\xE4\x8Ar
 		_snprintf_s(emsg_tmp, sizeof(emsg_tmp), _TRUNCATE,
 		            "%s: type mismatch for decoded server_host_key_blob (kex:%s blob:%s)", /*__FUNCTION__*/"handle_SSH2_ecdh_kex_reply",
-		            get_ssh_keytype_name(pvar->hostkey_type), get_ssh_keytype_name(hostkey->type));
+		            get_ssh2_hostkey_type_name(pvar->hostkey_type), get_ssh2_hostkey_type_name(hostkey->type));
 		emsg = emsg_tmp;
 		goto error;
 	}
@@ -7091,7 +6622,7 @@
 		s = "publickey";
 		buffer_put_string(signbuf, s, strlen(s));
 		buffer_put_char(signbuf, 1); // true
-		s = get_sshname_from_key(keypair); // key type\x82ɉ\x9E\x82\xB6\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82𓾂\xE9
+		s = get_ssh2_hostkey_type_name_from_key(keypair); // key type\x82ɉ\x9E\x82\xB6\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82𓾂\xE9
 		buffer_put_string(signbuf, s, strlen(s));
 		s = buffer_ptr(blob);
 		buffer_append_length(signbuf, s, bloblen);
@@ -7109,7 +6640,7 @@
 		s = "publickey";
 		buffer_put_string(msg, s, strlen(s));
 		buffer_put_char(msg, 1); // true
-		s = get_sshname_from_key(keypair); // key type\x82ɉ\x9E\x82\xB6\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82𓾂\xE9
+		s = get_ssh2_hostkey_type_name_from_key(keypair); // key type\x82ɉ\x9E\x82\xB6\x82\xBD\x95\xB6\x8E\x9A\x97\xF1\x82𓾂\xE9
 		buffer_put_string(msg, s, strlen(s));
 		s = buffer_ptr(blob);
 		buffer_append_length(msg, s, bloblen);

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.h	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -40,6 +40,10 @@
 
 #include "buffer.h"
 #include "config.h"
+#include "cipher.h"
+#include "hostkey.h"
+#include "mac.h"
+#include "comp.h"
 #include <sys/types.h>
 #include <sys/stat.h>
 
@@ -82,24 +86,6 @@
 } SSHMessage;
 
 typedef enum {
-	// SSH1
-	SSH_CIPHER_NONE, SSH_CIPHER_IDEA, SSH_CIPHER_DES, SSH_CIPHER_3DES,
-	SSH_CIPHER_TSS, SSH_CIPHER_RC4, SSH_CIPHER_BLOWFISH,
-	// SSH2
-	SSH2_CIPHER_3DES_CBC, SSH2_CIPHER_AES128_CBC,
-	SSH2_CIPHER_AES192_CBC, SSH2_CIPHER_AES256_CBC,
-	SSH2_CIPHER_BLOWFISH_CBC, SSH2_CIPHER_AES128_CTR,
-	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,
-	SSH2_CIPHER_CAMELLIA128_CBC, SSH2_CIPHER_CAMELLIA192_CBC, SSH2_CIPHER_CAMELLIA256_CBC,
-	SSH2_CIPHER_CAMELLIA128_CTR, SSH2_CIPHER_CAMELLIA192_CTR, SSH2_CIPHER_CAMELLIA256_CTR,
-	SSH2_CIPHER_AES128_GCM, SSH2_CIPHER_AES256_GCM,
-	SSH_CIPHER_MAX = SSH2_CIPHER_AES256_GCM,
-} SSHCipherId;
-
-typedef enum {
 	SSH_AUTH_NONE, SSH_AUTH_RHOSTS, SSH_AUTH_RSA, SSH_AUTH_PASSWORD,
 	SSH_AUTH_RHOSTS_RSA, SSH_AUTH_TIS, SSH_AUTH_KERBEROS,
 	SSH_AUTH_PAGEANT = 16,
@@ -298,73 +284,8 @@
 } SSH2TTYMode;
 
 
-// \x83N\x83\x89\x83C\x83A\x83\x93\x83g\x82\xA9\x82\xE7\x83T\x81[\x83o\x82ւ̒\xF1\x88Ď\x96\x8D\x80
-enum kex_init_proposals {
-	PROPOSAL_KEX_ALGS,
-	PROPOSAL_SERVER_HOST_KEY_ALGS,
-	PROPOSAL_ENC_ALGS_CTOS,
-	PROPOSAL_ENC_ALGS_STOC,
-	PROPOSAL_MAC_ALGS_CTOS,
-	PROPOSAL_MAC_ALGS_STOC,
-	PROPOSAL_COMP_ALGS_CTOS,
-	PROPOSAL_COMP_ALGS_STOC,
-	PROPOSAL_LANG_CTOS,
-	PROPOSAL_LANG_STOC,
-	PROPOSAL_MAX
-};
-
-#define KEX_DEFAULT_KEX     ""
-#define KEX_DEFAULT_PK_ALG  ""
-#define KEX_DEFAULT_ENCRYPT ""
-#define KEX_DEFAULT_MAC     ""
-#define KEX_DEFAULT_COMP    ""
-#define KEX_DEFAULT_LANG    ""
-
-static char *myproposal[PROPOSAL_MAX] = {
-	KEX_DEFAULT_KEX,
-	KEX_DEFAULT_PK_ALG,
-	KEX_DEFAULT_ENCRYPT,
-	KEX_DEFAULT_ENCRYPT,
-	KEX_DEFAULT_MAC,
-	KEX_DEFAULT_MAC,
-	KEX_DEFAULT_COMP,
-	KEX_DEFAULT_COMP,
-	KEX_DEFAULT_LANG,
-	KEX_DEFAULT_LANG,
-};
-
-
-typedef enum {
-	KEY_NONE,
-	KEY_RSA1,
-	KEY_RSA,
-	KEY_DSA,
-	KEY_ECDSA256,
-	KEY_ECDSA384,
-	KEY_ECDSA521,
-	KEY_ED25519,
-	KEY_UNSPEC,
-	KEY_MAX = KEY_UNSPEC,
-} ssh_keytype;
 #define isFixedLengthKey(type)	((type) >= KEY_DSA && (type) <= KEY_ED25519)
 
-typedef struct ssh2_host_key {
-	ssh_keytype type;
-	char *name;
-} ssh2_host_key_t;
-
-static ssh2_host_key_t ssh2_host_key[] = {
-	{KEY_RSA1,     "ssh-rsa1"},            // for SSH1 only
-	{KEY_RSA,      "ssh-rsa"},             // RFC4253
-	{KEY_DSA,      "ssh-dss"},             // RFC4253
-	{KEY_ECDSA256, "ecdsa-sha2-nistp256"}, // RFC5656
-	{KEY_ECDSA384, "ecdsa-sha2-nistp384"}, // RFC5656
-	{KEY_ECDSA521, "ecdsa-sha2-nistp521"}, // RFC5656
-	{KEY_ED25519,  "ssh-ed25519"},         // draft-bjh21-ssh-ed25519-02
-	{KEY_UNSPEC,   "ssh-unknown"},
-	{KEY_NONE,     NULL},
-};
-
 /* Minimum modulus size (n) for RSA keys. */
 #define SSH_RSA_MINIMUM_MODULUS_SIZE    768
 
@@ -376,165 +297,6 @@
 #define SSH_KEYGEN_MAXIMUM_ROUNDS INT_MAX
 
 
-typedef struct ssh2_cipher {
-	SSHCipherId id;
-	char *name;
-	int block_size;
-	int key_len;
-	int discard_len;
-	int iv_len;
-	int auth_len;
-	const EVP_CIPHER *(*func)(void);
-} SSH2Cipher;
-
-static SSH2Cipher ssh2_ciphers[] = {
-	{SSH2_CIPHER_3DES_CBC,        "3des-cbc",         8, 24,    0, 0, 0, EVP_des_ede3_cbc},     // RFC4253
-	{SSH2_CIPHER_AES128_CBC,      "aes128-cbc",      16, 16,    0, 0, 0, EVP_aes_128_cbc},      // RFC4253
-	{SSH2_CIPHER_AES192_CBC,      "aes192-cbc",      16, 24,    0, 0, 0, EVP_aes_192_cbc},      // RFC4253
-	{SSH2_CIPHER_AES256_CBC,      "aes256-cbc",      16, 32,    0, 0, 0, EVP_aes_256_cbc},      // RFC4253
-	{SSH2_CIPHER_BLOWFISH_CBC,    "blowfish-cbc",     8, 16,    0, 0, 0, EVP_bf_cbc},           // RFC4253
-	{SSH2_CIPHER_AES128_CTR,      "aes128-ctr",      16, 16,    0, 0, 0, evp_aes_128_ctr},      // RFC4344
-	{SSH2_CIPHER_AES192_CTR,      "aes192-ctr",      16, 24,    0, 0, 0, evp_aes_128_ctr},      // RFC4344
-	{SSH2_CIPHER_AES256_CTR,      "aes256-ctr",      16, 32,    0, 0, 0, evp_aes_128_ctr},      // RFC4344
-	{SSH2_CIPHER_ARCFOUR,         "arcfour",          8, 16,    0, 0, 0, EVP_rc4},              // RFC4253
-	{SSH2_CIPHER_ARCFOUR128,      "arcfour128",       8, 16, 1536, 0, 0, EVP_rc4},              // RFC4345
-	{SSH2_CIPHER_ARCFOUR256,      "arcfour256",       8, 32, 1536, 0, 0, EVP_rc4},              // RFC4345
-	{SSH2_CIPHER_CAST128_CBC,     "cast128-cbc",      8, 16,    0, 0, 0, EVP_cast5_cbc},        // RFC4253
-	{SSH2_CIPHER_3DES_CTR,        "3des-ctr",         8, 24,    0, 0, 0, evp_des3_ctr},         // RFC4344
-	{SSH2_CIPHER_BLOWFISH_CTR,    "blowfish-ctr",     8, 32,    0, 0, 0, evp_bf_ctr},           // RFC4344
-	{SSH2_CIPHER_CAST128_CTR,     "cast128-ctr",      8, 16,    0, 0, 0, evp_cast5_ctr},        // RFC4344
-	{SSH2_CIPHER_CAMELLIA128_CBC, "camellia128-cbc", 16, 16,    0, 0, 0, EVP_camellia_128_cbc}, // draft-kanno-secsh-camellia-02
-	{SSH2_CIPHER_CAMELLIA192_CBC, "camellia192-cbc", 16, 24,    0, 0, 0, EVP_camellia_192_cbc}, // draft-kanno-secsh-camellia-02
-	{SSH2_CIPHER_CAMELLIA256_CBC, "camellia256-cbc", 16, 32,    0, 0, 0, EVP_camellia_256_cbc}, // draft-kanno-secsh-camellia-02
-	{SSH2_CIPHER_CAMELLIA128_CTR, "camellia128-ctr", 16, 16,    0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
-	{SSH2_CIPHER_CAMELLIA192_CTR, "camellia192-ctr", 16, 24,    0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
-	{SSH2_CIPHER_CAMELLIA256_CTR, "camellia256-ctr", 16, 32,    0, 0, 0, evp_camellia_128_ctr}, // draft-kanno-secsh-camellia-02
-#ifdef WITH_CAMELLIA_PRIVATE
-	{SSH2_CIPHER_CAMELLIA128_CBC, "camel****@opens*****", 16, 16, 0,  0,  0, EVP_camellia_128_cbc},
-	{SSH2_CIPHER_CAMELLIA192_CBC, "camel****@opens*****", 16, 24, 0,  0,  0, EVP_camellia_192_cbc},
-	{SSH2_CIPHER_CAMELLIA256_CBC, "camel****@opens*****", 16, 32, 0,  0,  0, EVP_camellia_256_cbc},
-	{SSH2_CIPHER_CAMELLIA128_CTR, "camel****@opens*****", 16, 16, 0,  0,  0, evp_camellia_128_ctr},
-	{SSH2_CIPHER_CAMELLIA192_CTR, "camel****@opens*****", 16, 24, 0,  0,  0, evp_camellia_128_ctr},
-	{SSH2_CIPHER_CAMELLIA256_CTR, "camel****@opens*****", 16, 32, 0,  0,  0, evp_camellia_128_ctr},
-#endif // WITH_CAMELLIA_PRIVATE
-	{SSH2_CIPHER_AES128_GCM,      "aes12****@opens*****",      16, 16, 0, 12, 16, EVP_aes_128_gcm}, // not RFC5647, PROTOCOL of OpenSSH
-	{SSH2_CIPHER_AES256_GCM,      "aes25****@opens*****",      16, 32, 0, 12, 16, EVP_aes_256_gcm}, // not RFC5647, PROTOCOL of OpenSSH
-	{SSH_CIPHER_NONE,             NULL,               0,  0,    0, 0, 0, NULL},
-};
-
-
-typedef enum {
-	KEX_DH_NONE,       /* disabled line */
-	KEX_DH_GRP1_SHA1,
-	KEX_DH_GRP14_SHA1,
-	KEX_DH_GEX_SHA1,
-	KEX_DH_GEX_SHA256,
-	KEX_ECDH_SHA2_256,
-	KEX_ECDH_SHA2_384,
-	KEX_ECDH_SHA2_521,
-	KEX_DH_GRP14_SHA256,
-	KEX_DH_GRP16_SHA512,
-	KEX_DH_GRP18_SHA512,
-	KEX_DH_UNKNOWN,
-	KEX_DH_MAX = KEX_DH_UNKNOWN,
-} kex_algorithm;
-
-typedef struct ssh2_kex_algorithm {
-	kex_algorithm kextype;
-	char *name;
-	const EVP_MD *(*evp_md)(void);
-} ssh2_kex_algorithm_t;
-
-static ssh2_kex_algorithm_t ssh2_kex_algorithms[] = {
-	{KEX_DH_GRP1_SHA1,  "diffie-hellman-group1-sha1",           EVP_sha1},   // RFC4253
-	{KEX_DH_GRP14_SHA1, "diffie-hellman-group14-sha1",          EVP_sha1},   // RFC4253
-	{KEX_DH_GEX_SHA1,   "diffie-hellman-group-exchange-sha1",   EVP_sha1},   // RFC4419
-	{KEX_DH_GEX_SHA256, "diffie-hellman-group-exchange-sha256", EVP_sha256}, // RFC4419
-	{KEX_ECDH_SHA2_256, "ecdh-sha2-nistp256",                   EVP_sha256}, // RFC5656
-	{KEX_ECDH_SHA2_384, "ecdh-sha2-nistp384",                   EVP_sha384}, // RFC5656
-	{KEX_ECDH_SHA2_521, "ecdh-sha2-nistp521",                   EVP_sha512}, // RFC5656
-	{KEX_DH_GRP14_SHA256, "diffie-hellman-group14-sha256",      EVP_sha256}, // RFC8268
-	{KEX_DH_GRP16_SHA512, "diffie-hellman-group16-sha512",      EVP_sha512}, // RFC8268
-	{KEX_DH_GRP18_SHA512, "diffie-hellman-group18-sha512",      EVP_sha512}, // RFC8268
-	{KEX_DH_NONE      , NULL,                                   NULL},
-};
-
-
-typedef enum {
-	HMAC_NONE,      /* disabled line */
-	HMAC_SHA1,
-	HMAC_MD5,
-	HMAC_SHA1_96,
-	HMAC_MD5_96,
-	HMAC_RIPEMD160,
-	HMAC_SHA2_256,
-	HMAC_SHA2_256_96,
-	HMAC_SHA2_512,
-	HMAC_SHA2_512_96,
-	HMAC_SHA1_EtM,
-	HMAC_MD5_EtM,
-	HMAC_SHA1_96_EtM,
-	HMAC_MD5_96_EtM,
-	HMAC_RIPEMD160_EtM,
-	HMAC_SHA2_256_EtM,
-	HMAC_SHA2_512_EtM,
-	HMAC_IMPLICIT,
-	HMAC_UNKNOWN,
-	HMAC_MAX = HMAC_UNKNOWN,
-} SSH2MacId;
-
-typedef struct ssh2_mac {
-	SSH2MacId id;
-	char *name;
-	const EVP_MD *(*evp_md)(void);
-	int truncatebits;
-	int etm;
-} SSH2Mac;
-
-static SSH2Mac ssh2_macs[] = {
-	{HMAC_SHA1,         "hmac-sha1",                     EVP_sha1,      0,  0}, // RFC4253
-	{HMAC_MD5,          "hmac-md5",                      EVP_md5,       0,  0}, // RFC4253
-	{HMAC_SHA1_96,      "hmac-sha1-96",                  EVP_sha1,      96, 0}, // RFC4253
-	{HMAC_MD5_96,       "hmac-md5-96",                   EVP_md5,       96, 0}, // RFC4253
-	{HMAC_RIPEMD160,    "hmac-****@opens*****",    EVP_ripemd160, 0,  0},
-	{HMAC_SHA2_256,     "hmac-sha2-256",                 EVP_sha256,    0,  0}, // RFC6668
-//	{HMAC_SHA2_256_96,  "hmac-sha2-256-96",              EVP_sha256,    96, 0}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06
-	{HMAC_SHA2_512,     "hmac-sha2-512",                 EVP_sha512,    0,  0}, // RFC6668
-//	{HMAC_SHA2_512_96,  "hmac-sha2-512-96",              EVP_sha512,    96, 0}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06
-	{HMAC_SHA1_EtM,     "hmac-****@opens*****",     EVP_sha1,      0,  1},
-	{HMAC_MD5_EtM,      "hmac-****@opens*****",      EVP_md5,       0,  1},
-	{HMAC_SHA1_96_EtM,  "hmac-****@opens*****",  EVP_sha1,      96, 1},
-	{HMAC_MD5_96_EtM,   "hmac-****@opens*****",   EVP_md5,       96, 1},
-	{HMAC_RIPEMD160_EtM,"hmac-****@opens*****",EVP_ripemd160, 0,  1},
-	{HMAC_SHA2_256_EtM, "hmac-****@opens*****", EVP_sha256,    0,  1},
-	{HMAC_SHA2_512_EtM, "hmac-****@opens*****", EVP_sha512,    0,  1},
-	{HMAC_IMPLICIT,     "<implicit>",                    EVP_md_null,   0,  0}, // for AEAD cipher
-	{HMAC_NONE,         NULL,                            NULL,          0,  0},
-};
-
-
-typedef enum {
-	COMP_NONE,      /* disabled line */
-	COMP_NOCOMP,
-	COMP_ZLIB,
-	COMP_DELAYED,
-	COMP_UNKNOWN,
-	COMP_MAX = COMP_UNKNOWN,
-} compression_type;
-
-typedef struct ssh2_comp {
-	compression_type type;
-	char *name;
-} ssh2_comp_t;
-
-static ssh2_comp_t ssh2_comps[] = {
-	{COMP_NOCOMP,  "none"},             // RFC4253
-	{COMP_ZLIB,    "zlib"},             // RFC4253
-	{COMP_DELAYED, "zlib****@opens*****"},
-	{COMP_NONE,    NULL},
-};
-
-
 struct Enc {
 	u_char          *key;
 	u_char          *iv;
@@ -595,47 +357,7 @@
 	int bcrypt_kdf;
 } Key;
 
-// fingerprint\x82̎\xED\x95\xCA
-enum fp_rep {
-	SSH_FP_DEFAULT = 0,
-	SSH_FP_HEX,
-	SSH_FP_BASE64,
-	SSH_FP_BUBBLEBABBLE,
-	SSH_FP_RANDOMART
-};
-/*
-enum fp_type {
-	SSH_FP_MD5,
-	SSH_FP_SHA1,
-	SSH_FP_SHA256
-};
-*/
-typedef enum {
-	SSH_DIGEST_MD5,
-	SSH_DIGEST_RIPEMD160,
-	SSH_DIGEST_SHA1,
-	SSH_DIGEST_SHA256,
-	SSH_DIGEST_SHA384,
-	SSH_DIGEST_SHA512,
-	SSH_DIGEST_MAX,
-} digest_algorithm;
 
-typedef struct ssh_digest {
-	digest_algorithm id;
-	char *name;
-} ssh_digest_t;
-
-/* NB. Indexed directly by algorithm number */
-static ssh_digest_t ssh_digests[] = {
-	{ SSH_DIGEST_MD5,       "MD5" },
-	{ SSH_DIGEST_RIPEMD160, "RIPEMD160" },
-	{ SSH_DIGEST_SHA1,      "SHA1" },
-	{ SSH_DIGEST_SHA256,    "SHA256" },
-	{ SSH_DIGEST_SHA384,    "SHA384" },
-	{ SSH_DIGEST_SHA512,    "SHA512" },
-	{ SSH_DIGEST_MAX,       NULL },
-};
-
 enum scp_dir {
 	TOREMOTE, FROMREMOTE,
 };
@@ -777,23 +499,6 @@
 BOOL do_SSH2_userauth(PTInstVar pvar);
 BOOL do_SSH2_authrequest(PTInstVar pvar);
 void debug_print(int no, char *msg, int len);
-int get_cipher_block_size(SSH2Cipher *cipher);
-int get_cipher_key_len(SSH2Cipher *cipher);
-int get_cipher_iv_len(SSH2Cipher *cipher);
-int get_cipher_auth_len(SSH2Cipher *cipher);
-SSH2Cipher *get_cipher_by_name(char *name);
-char* get_kex_algorithm_name(kex_algorithm kextype);
-const EVP_CIPHER* get_cipher_EVP_CIPHER(SSH2Cipher *cipher);
-const EVP_MD* get_kex_algorithm_EVP_MD(kex_algorithm kextype);
-SSH2Mac *get_ssh2_mac(SSH2MacId id);
-char* get_ssh2_mac_name(SSH2Mac *mac);
-char* get_ssh2_mac_name_by_id(SSH2MacId id);
-const EVP_MD* get_ssh2_mac_EVP_MD(SSH2Mac *mac);
-int get_ssh2_mac_truncatebits(SSH2Mac *mac);
-char* get_ssh2_comp_name(compression_type type);
-char* get_ssh_keytype_name(ssh_keytype type);
-char* get_digest_algorithm_name(digest_algorithm id);
-int get_cipher_discard_len(SSH2Cipher *cipher);
 void ssh_heartbeat_lock_initialize(void);
 void ssh_heartbeat_lock_finalize(void);
 void ssh_heartbeat_lock(void);
@@ -804,11 +509,6 @@
 BOOL handle_SSH2_userauth_inforeq(PTInstVar pvar);
 BOOL handle_SSH2_userauth_pkok(PTInstVar pvar);
 BOOL handle_SSH2_userauth_passwd_changereq(PTInstVar pvar);
-void SSH2_update_compression_myproposal(PTInstVar pvar);
-void SSH2_update_cipher_myproposal(PTInstVar pvar);
-void SSH2_update_kex_myproposal(PTInstVar pvar);
-void SSH2_update_host_key_myproposal(PTInstVar pvar);
-void SSH2_update_hmac_myproposal(PTInstVar pvar);
 int SSH_notify_break_signal(PTInstVar pvar);
 
 ///
@@ -896,6 +596,8 @@
 void finish_send_packet_special(PTInstVar pvar, int skip_compress);
 void SSH2_send_channel_data(PTInstVar pvar, Channel_t *c, unsigned char *buf, unsigned int buflen, int retry);
 Channel_t* ssh2_local_channel_lookup(int local_num);
+void normalize_generic_order(char *buf, char default_strings[], int default_strings_len);
+void choose_SSH2_proposal(char* server_proposal, char* my_proposal,char* dest, int dest_len);
 
 #define finish_send_packet(pvar) finish_send_packet_special((pvar), 0)
 #define get_payload_uint32(pvar, offset) get_uint32_MSBfirst((pvar)->ssh_state.payload + (offset))
@@ -944,4 +646,4 @@
 BOOL handle_SSH2_dh_gex_reply_after_known_hosts(PTInstVar pvar);
 BOOL handle_SSH2_ecdh_kex_reply_after_known_hosts(PTInstVar pvar);
 
-#endif
+#endif /* __SSH_H */

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,153 @@
+/* Imported via OpenSSH-8.5p1, TeraTerm Project */
+
+/*	$OpenBSD: ssherr.c,v 1.10 2020/01/25 23:13:09 djm Exp $	*/
+/*
+ * Copyright (c) 2011 Damien Miller
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <errno.h>
+#include <string.h>
+#include "ssherr.h"
+
+const char *
+ssh_err(int n)
+{
+	switch (n) {
+	case SSH_ERR_SUCCESS:
+		return "success";
+	case SSH_ERR_INTERNAL_ERROR:
+		return "unexpected internal error";
+	case SSH_ERR_ALLOC_FAIL:
+		return "memory allocation failed";
+	case SSH_ERR_MESSAGE_INCOMPLETE:
+		return "incomplete message";
+	case SSH_ERR_INVALID_FORMAT:
+		return "invalid format";
+	case SSH_ERR_BIGNUM_IS_NEGATIVE:
+		return "bignum is negative";
+	case SSH_ERR_STRING_TOO_LARGE:
+		return "string is too large";
+	case SSH_ERR_BIGNUM_TOO_LARGE:
+		return "bignum is too large";
+	case SSH_ERR_ECPOINT_TOO_LARGE:
+		return "elliptic curve point is too large";
+	case SSH_ERR_NO_BUFFER_SPACE:
+		return "insufficient buffer space";
+	case SSH_ERR_INVALID_ARGUMENT:
+		return "invalid argument";
+	case SSH_ERR_KEY_BITS_MISMATCH:
+		return "key bits do not match";
+	case SSH_ERR_EC_CURVE_INVALID:
+		return "invalid elliptic curve";
+	case SSH_ERR_KEY_TYPE_MISMATCH:
+		return "key type does not match";
+	case SSH_ERR_KEY_TYPE_UNKNOWN:
+		return "unknown or unsupported key type";
+	case SSH_ERR_EC_CURVE_MISMATCH:
+		return "elliptic curve does not match";
+	case SSH_ERR_EXPECTED_CERT:
+		return "plain key provided where certificate required";
+	case SSH_ERR_KEY_LACKS_CERTBLOB:
+		return "key lacks certificate data";
+	case SSH_ERR_KEY_CERT_UNKNOWN_TYPE:
+		return "unknown/unsupported certificate type";
+	case SSH_ERR_KEY_CERT_INVALID_SIGN_KEY:
+		return "invalid certificate signing key";
+	case SSH_ERR_KEY_INVALID_EC_VALUE:
+		return "invalid elliptic curve value";
+	case SSH_ERR_SIGNATURE_INVALID:
+		return "incorrect signature";
+	case SSH_ERR_LIBCRYPTO_ERROR:
+		return "error in libcrypto";  /* XXX fetch and return */
+	case SSH_ERR_UNEXPECTED_TRAILING_DATA:
+		return "unexpected bytes remain after decoding";
+	case SSH_ERR_SYSTEM_ERROR:
+		return strerror(errno);
+	case SSH_ERR_KEY_CERT_INVALID:
+		return "invalid certificate";
+	case SSH_ERR_AGENT_COMMUNICATION:
+		return "communication with agent failed";
+	case SSH_ERR_AGENT_FAILURE:
+		return "agent refused operation";
+	case SSH_ERR_DH_GEX_OUT_OF_RANGE:
+		return "DH GEX group out of range";
+	case SSH_ERR_DISCONNECTED:
+		return "disconnected";
+	case SSH_ERR_MAC_INVALID:
+		return "message authentication code incorrect";
+	case SSH_ERR_NO_CIPHER_ALG_MATCH:
+		return "no matching cipher found";
+	case SSH_ERR_NO_MAC_ALG_MATCH:
+		return "no matching MAC found";
+	case SSH_ERR_NO_COMPRESS_ALG_MATCH:
+		return "no matching compression method found";
+	case SSH_ERR_NO_KEX_ALG_MATCH:
+		return "no matching key exchange method found";
+	case SSH_ERR_NO_HOSTKEY_ALG_MATCH:
+		return "no matching host key type found";
+	case SSH_ERR_PROTOCOL_MISMATCH:
+		return "protocol version mismatch";
+	case SSH_ERR_NO_PROTOCOL_VERSION:
+		return "could not read protocol version";
+	case SSH_ERR_NO_HOSTKEY_LOADED:
+		return "could not load host key";
+	case SSH_ERR_NEED_REKEY:
+		return "rekeying not supported by peer";
+	case SSH_ERR_PASSPHRASE_TOO_SHORT:
+		return "passphrase is too short (minimum five characters)";
+	case SSH_ERR_FILE_CHANGED:
+		return "file changed while reading";
+	case SSH_ERR_KEY_UNKNOWN_CIPHER:
+		return "key encrypted using unsupported cipher";
+	case SSH_ERR_KEY_WRONG_PASSPHRASE:
+		return "incorrect passphrase supplied to decrypt private key";
+	case SSH_ERR_KEY_BAD_PERMISSIONS:
+		return "bad permissions";
+	case SSH_ERR_KEY_CERT_MISMATCH:
+		return "certificate does not match key";
+	case SSH_ERR_KEY_NOT_FOUND:
+		return "key not found";
+	case SSH_ERR_AGENT_NOT_PRESENT:
+		return "agent not present";
+	case SSH_ERR_AGENT_NO_IDENTITIES:
+		return "agent contains no identities";
+	case SSH_ERR_BUFFER_READ_ONLY:
+		return "internal error: buffer is read-only";
+	case SSH_ERR_KRL_BAD_MAGIC:
+		return "KRL file has invalid magic number";
+	case SSH_ERR_KEY_REVOKED:
+		return "Key is revoked";
+	case SSH_ERR_CONN_CLOSED:
+		return "Connection closed";
+	case SSH_ERR_CONN_TIMEOUT:
+		return "Connection timed out";
+	case SSH_ERR_CONN_CORRUPT:
+		return "Connection corrupted";
+	case SSH_ERR_PROTOCOL_ERROR:
+		return "Protocol error";
+	case SSH_ERR_KEY_LENGTH:
+		return "Invalid key length";
+	case SSH_ERR_NUMBER_TOO_LARGE:
+		return "number is too large";
+	case SSH_ERR_SIGN_ALG_UNSUPPORTED:
+		return "signature algorithm not supported";
+	case SSH_ERR_FEATURE_UNSUPPORTED:
+		return "requested feature not supported";
+	case SSH_ERR_DEVICE_NOT_FOUND:
+		return "device not found";
+	default:
+		return "unknown error";
+	}
+}

Added: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h	                        (rev 0)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -0,0 +1,91 @@
+/* Imported via OpenSSH-8.5p1, TeraTerm Project */
+
+/*	$OpenBSD: ssherr.h,v 1.8 2020/01/25 23:13:09 djm Exp $	*/
+/*
+ * Copyright (c) 2011 Damien Miller
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#ifndef _SSHERR_H
+#define _SSHERR_H
+
+/* XXX are these too granular? not granular enough? I can't decide - djm */
+
+/* Error codes */
+#define SSH_ERR_SUCCESS				0
+#define SSH_ERR_INTERNAL_ERROR			-1
+#define SSH_ERR_ALLOC_FAIL			-2
+#define SSH_ERR_MESSAGE_INCOMPLETE		-3
+#define SSH_ERR_INVALID_FORMAT			-4
+#define SSH_ERR_BIGNUM_IS_NEGATIVE		-5
+#define SSH_ERR_STRING_TOO_LARGE		-6
+#define SSH_ERR_BIGNUM_TOO_LARGE		-7
+#define SSH_ERR_ECPOINT_TOO_LARGE		-8
+#define SSH_ERR_NO_BUFFER_SPACE			-9
+#define SSH_ERR_INVALID_ARGUMENT		-10
+#define SSH_ERR_KEY_BITS_MISMATCH		-11
+#define SSH_ERR_EC_CURVE_INVALID		-12
+#define SSH_ERR_KEY_TYPE_MISMATCH		-13
+#define SSH_ERR_KEY_TYPE_UNKNOWN		-14 /* XXX UNSUPPORTED? */
+#define SSH_ERR_EC_CURVE_MISMATCH		-15
+#define SSH_ERR_EXPECTED_CERT			-16
+#define SSH_ERR_KEY_LACKS_CERTBLOB		-17
+#define SSH_ERR_KEY_CERT_UNKNOWN_TYPE		-18
+#define SSH_ERR_KEY_CERT_INVALID_SIGN_KEY	-19
+#define SSH_ERR_KEY_INVALID_EC_VALUE		-20
+#define SSH_ERR_SIGNATURE_INVALID		-21
+#define SSH_ERR_LIBCRYPTO_ERROR			-22
+#define SSH_ERR_UNEXPECTED_TRAILING_DATA	-23
+#define SSH_ERR_SYSTEM_ERROR			-24
+#define SSH_ERR_KEY_CERT_INVALID		-25
+#define SSH_ERR_AGENT_COMMUNICATION		-26
+#define SSH_ERR_AGENT_FAILURE			-27
+#define SSH_ERR_DH_GEX_OUT_OF_RANGE		-28
+#define SSH_ERR_DISCONNECTED			-29
+#define SSH_ERR_MAC_INVALID			-30
+#define SSH_ERR_NO_CIPHER_ALG_MATCH		-31
+#define SSH_ERR_NO_MAC_ALG_MATCH		-32
+#define SSH_ERR_NO_COMPRESS_ALG_MATCH		-33
+#define SSH_ERR_NO_KEX_ALG_MATCH		-34
+#define SSH_ERR_NO_HOSTKEY_ALG_MATCH		-35
+#define SSH_ERR_NO_HOSTKEY_LOADED		-36
+#define SSH_ERR_PROTOCOL_MISMATCH		-37
+#define SSH_ERR_NO_PROTOCOL_VERSION		-38
+#define SSH_ERR_NEED_REKEY			-39
+#define SSH_ERR_PASSPHRASE_TOO_SHORT		-40
+#define SSH_ERR_FILE_CHANGED			-41
+#define SSH_ERR_KEY_UNKNOWN_CIPHER		-42
+#define SSH_ERR_KEY_WRONG_PASSPHRASE		-43
+#define SSH_ERR_KEY_BAD_PERMISSIONS		-44
+#define SSH_ERR_KEY_CERT_MISMATCH		-45
+#define SSH_ERR_KEY_NOT_FOUND			-46
+#define SSH_ERR_AGENT_NOT_PRESENT		-47
+#define SSH_ERR_AGENT_NO_IDENTITIES		-48
+#define SSH_ERR_BUFFER_READ_ONLY		-49
+#define SSH_ERR_KRL_BAD_MAGIC			-50
+#define SSH_ERR_KEY_REVOKED			-51
+#define SSH_ERR_CONN_CLOSED			-52
+#define SSH_ERR_CONN_TIMEOUT			-53
+#define SSH_ERR_CONN_CORRUPT			-54
+#define SSH_ERR_PROTOCOL_ERROR			-55
+#define SSH_ERR_KEY_LENGTH			-56
+#define SSH_ERR_NUMBER_TOO_LARGE		-57
+#define SSH_ERR_SIGN_ALG_UNSUPPORTED		-58
+#define SSH_ERR_FEATURE_UNSUPPORTED		-59
+#define SSH_ERR_DEVICE_NOT_FOUND		-60
+
+/* Translate a numeric error code to a human-readable error string */
+const char *ssh_err(int n);
+
+#endif /* _SSHERR_H */

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.c	2021-04-17 08:36:59 UTC (rev 9210)
@@ -78,6 +78,9 @@
 #include "buffer.h"
 #include "cipher.h"
 #include "key.h"
+#include "kex.h"
+#include "mac.h"
+#include "comp.h"
 #include "dlglib.h"
 
 #include "sftp.h"
@@ -87,6 +90,9 @@
 
 #include "libputty.h"
 
+// from cipher-3des.c
+extern const EVP_CIPHER* evp_ssh1_3des(void);
+
 #undef DialogBoxParam
 #define DialogBoxParam(p1,p2,p3,p4,p5) \
 	TTDialogBoxParam(p1,p2,p3,p4,p5)
@@ -207,208 +213,6 @@
 	init_TTSSH(pvar);
 }
 
-static void normalize_generic_order(char *buf, char default_strings[], int default_strings_len)
-{
-	char listed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1];
-	char allowed[max(KEX_DH_MAX,max(SSH_CIPHER_MAX,max(KEY_MAX,max(HMAC_MAX,COMP_MAX)))) + 1];
-	int i, j, k=-1;
-
-	memset(listed, 0, sizeof(listed));
-	memset(allowed, 0, sizeof(allowed));
-
-	// \x8B\x96\x89‚\xB3\x82\xEA\x82Ă\xA2\x82镶\x8E\x9A\x82̃\x8A\x83X\x83g\x82\xF0\x8D\xEC\x82\xE9\x81B
-	for (i = 0; i < default_strings_len ; i++) {
-		allowed[default_strings[i]] = 1;
-	}
-
-	// \x8Ew\x92肳\x82ꂽ\x95\xB6\x8E\x9A\x97\xF1\x82𑖍\xB8\x82\xB5\x81A\x8B\x96\x89‚\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x95\xB6\x8E\x9A\x81A\x8Fd\x95\xA1\x82\xB7\x82镶\x8E\x9A\x82͍폜\x82\xB7\x82\xE9\x81B
-	// 
-	// ex. (i=5 \x82̕\xB6\x8E\x9A\x82\xF0\x8D폜\x82\xB7\x82\xE9)
-	// i=012345
-	//   >:=9<87;A@?B3026(\0)
-	//         i+1
-	//         <------------>
-	//       \x81\xAB
-	//   >:=9<7;A@?B3026(\0)
-	//         
-	for (i = 0; buf[i] != 0; i++) {
-		int num = buf[i] - '0';
-
-		if (num < 0 || num > default_strings_len
-			|| !allowed[num]
-			|| listed[num]) {
-			memmove(buf + i, buf + i + 1, strlen(buf + i + 1) + 1);
-			i--;
-		} else {
-			listed[num] = 1;
-		}
-
-		// disabled line\x82\xAA\x82\xA0\x82\xEA\x82΁A\x88ʒu\x82\xF0\x8Ao\x82\xA6\x82Ă\xA8\x82\xAD\x81B
-		if (num == 0) {
-			k = i;
-		}
-	}
-
-	// \x8Ew\x92肳\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x95\xB6\x8E\x9A\x82\xAA\x82\xA0\x82\xEA\x82΁Adisabled line\x82̒\xBC\x91O\x82ɑ}\x93\xFC\x82\xB7\x82\xE9\x81B
-	// 
-	// ex. (Z\x82\xF0\x91}\x93\xFC\x82\xB7\x82\xE9)
-	//                k
-	//   >:=9<87;A@?B3026(\0)
-	//                 k+1
-	//                 <---->
-	//       \x81\xAB       k
-	//   >:=9<87;A@?B30026(\0)
-	//       \x81\xAB        k
-	//   >:=9<87;A@?B3Z026(\0)
-	//       
-	for (j = 0; j < default_strings_len && default_strings[j] != 0; j++) {
-		int num = default_strings[j];
-
-		if (!listed[num] && k >= 0) {
-			int copylen = strlen(buf + k + 1) + 1;
-
-			memmove(buf + k + 1, buf + k, copylen);
-			buf[k + 1 + copylen] = '\0';   // \x8FI\x92[\x82\xF0\x96Y\x82ꂸ\x82ɕt\x82\xAF\x82\xE9\x81B
-			buf[k] = num + '0';
-			k++;
-			i++;
-		}
-	}
-	if (k < 0) {
-		j = 0;
-	}
-	else {
-		j++;
-	}
-
-	// disabled line\x82\xAA\x91\xB6\x8D݂\xB5\x82Ȃ\xA2\x8Fꍇ\x82́A\x82\xBB\x82̂܂ܖ\x96\x94\xF6\x82ɒlj\xC1\x82\xB7\x82\xE9\x81B
-	for (; j < default_strings_len ; j++) {
-		int num = default_strings[j];
-
-		if (!listed[num]) {
-			buf[i] = num + '0';
-			listed[num] = 1;
-			i++;
-		}
-	}
-
-	buf[i] = 0;
-}
-
-/*
- * Remove unsupported cipher or duplicated cipher.
- * Add unspecified ciphers at the end of list.
- */
-static void normalize_cipher_order(char *buf)
-{
-	/* SSH_CIPHER_NONE means that all ciphers below that one are disabled.
-	   We *never* allow no encryption. */
-	static char default_strings[] = {
-		SSH2_CIPHER_AES256_GCM,
-		SSH2_CIPHER_CAMELLIA256_CTR,
-		SSH2_CIPHER_AES256_CTR,
-		SSH2_CIPHER_CAMELLIA256_CBC,
-		SSH2_CIPHER_AES256_CBC,
-		SSH2_CIPHER_CAMELLIA192_CTR,
-		SSH2_CIPHER_AES192_CTR,
-		SSH2_CIPHER_CAMELLIA192_CBC,
-		SSH2_CIPHER_AES192_CBC,
-		SSH2_CIPHER_AES128_GCM,
-		SSH2_CIPHER_CAMELLIA128_CTR,
-		SSH2_CIPHER_AES128_CTR,
-		SSH2_CIPHER_CAMELLIA128_CBC,
-		SSH2_CIPHER_AES128_CBC,
-		SSH2_CIPHER_3DES_CTR,
-		SSH2_CIPHER_3DES_CBC,
-		SSH2_CIPHER_BLOWFISH_CTR,
-		SSH2_CIPHER_BLOWFISH_CBC,
-		SSH2_CIPHER_CAST128_CTR,
-		SSH2_CIPHER_CAST128_CBC,
-		SSH_CIPHER_3DES,
-		SSH_CIPHER_NONE,
-		SSH2_CIPHER_ARCFOUR256,
-		SSH2_CIPHER_ARCFOUR128,
-		SSH2_CIPHER_ARCFOUR,
-		SSH_CIPHER_BLOWFISH,
-		SSH_CIPHER_DES,
-		0, 0, 0 // Dummy for SSH_CIPHER_IDEA, SSH_CIPHER_TSS, SSH_CIPHER_RC4
-	};
-
-	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
-}
-
-static void normalize_kex_order(char *buf)
-{
-	static char default_strings[] = {
-		KEX_ECDH_SHA2_256,
-		KEX_ECDH_SHA2_384,
-		KEX_ECDH_SHA2_521,
-		KEX_DH_GRP18_SHA512,
-		KEX_DH_GRP16_SHA512,
-		KEX_DH_GRP14_SHA256,
-		KEX_DH_GEX_SHA256,
-		KEX_DH_GEX_SHA1,
-		KEX_DH_GRP14_SHA1,
-		KEX_DH_GRP1_SHA1,
-		KEX_DH_NONE,
-	};
-
-	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
-}
-
-static void normalize_host_key_order(char *buf)
-{
-	static char default_strings[] = {
-		KEY_ECDSA256,
-		KEY_ECDSA384,
-		KEY_ECDSA521,
-		KEY_ED25519,
-		KEY_RSA,
-		KEY_DSA,
-		KEY_NONE,
-	};
-
-	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
-}
-
-static void normalize_mac_order(char *buf)
-{
-	static char default_strings[] = {
-		HMAC_SHA2_512_EtM,
-		HMAC_SHA2_256_EtM,
-		HMAC_SHA1_EtM,
-		HMAC_SHA2_512,
-		HMAC_SHA2_256,
-		HMAC_SHA1,
-		HMAC_RIPEMD160_EtM,
-		HMAC_RIPEMD160,
-		HMAC_MD5_EtM,
-		HMAC_MD5,
-		HMAC_NONE,
-		HMAC_SHA1_96_EtM,
-		HMAC_MD5_96_EtM,
-		HMAC_SHA1_96,
-		HMAC_MD5_96,
-		0, // Dummy for HMAC_SHA2_512_96,
-		0, // Dummy for HMAC_SHA2_256_96,
-	};
-
-	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
-}
-
-static void normalize_comp_order(char *buf)
-{
-	static char default_strings[] = {
-		COMP_DELAYED,
-		COMP_ZLIB,
-		COMP_NOCOMP,
-		COMP_NONE,
-	};
-
-	normalize_generic_order(buf, default_strings, NUM_ELEM(default_strings));
-}
-
-
 /* Remove local settings from the shared memory block. */
 static void clear_local_settings(PTInstVar pvar)
 {
@@ -1145,7 +949,7 @@
 		HOSTS_open(pvar);
 		FWDUI_open(pvar);
 
-		// \x90ݒ\xE8\x82\xF0 myproposal \x82ɔ\xBD\x89f\x82\xB7\x82\xE9\x82̂́A\x90ڑ\xB1\x92\xBC\x91O\x82̂\xB1\x82\xB1\x82\xBE\x82\xAF\x81B (2006.6.26 maya)
+		// \x90ݒ\xE8\x82\xF0 myproposal \x82ɔ\xBD\x89f\x82\xB7\x82\xE9\x82̂́A\x90ڑ\xB1\x92\xBC\x91O\x82̂\xB1\x82\xB1\x82\xBE\x82\xAF\x81B
 		SSH2_update_kex_myproposal(pvar);
 		SSH2_update_host_key_myproposal(pvar);
 		SSH2_update_cipher_myproposal(pvar);
@@ -2292,7 +2096,7 @@
 			UTIL_get_lang_msg("DLG_ABOUT_HOSTKEY", pvar, "Host Key:");
 			strncat_s(buf2, sizeof(buf2), pvar->ts->UIMsg, _TRUNCATE);
 			strncat_s(buf2, sizeof(buf2), " ", _TRUNCATE);
-			strncat_s(buf2, sizeof(buf2), get_ssh_keytype_name(pvar->hostkey_type), _TRUNCATE);
+			strncat_s(buf2, sizeof(buf2), get_ssh2_hostkey_type_name(pvar->hostkey_type), _TRUNCATE);
 			strncat_s(buf2, sizeof(buf2), "\r\n", _TRUNCATE);
 
 			UTIL_get_lang_msg("DLG_ABOUT_ENCRYPTION", pvar, "Encryption:");
@@ -2531,73 +2335,6 @@
 	return FALSE;
 }
 
-static char *get_cipher_name(int cipher)
-{
-	switch (cipher) {
-	case SSH_CIPHER_NONE:
-		UTIL_get_lang_msg("DLG_SSHSETUP_CIPHER_BORDER", pvar,
-		                  "<ciphers below this line are disabled>");
-		return pvar->ts->UIMsg;
-	case SSH_CIPHER_3DES:
-		return "3DES(SSH1)";
-	case SSH_CIPHER_DES:
-		return "DES(SSH1)";
-	case SSH_CIPHER_BLOWFISH:
-		return "Blowfish(SSH1)";
-
-	// for SSH2(yutaka)
-	case SSH2_CIPHER_AES128_CBC:
-		return "aes128-cbc(SSH2)";
-	case SSH2_CIPHER_AES192_CBC:
-		return "aes192-cbc(SSH2)";
-	case SSH2_CIPHER_AES256_CBC:
-		return "aes256-cbc(SSH2)";
-	case SSH2_CIPHER_3DES_CBC:
-		return "3des-cbc(SSH2)";
-	case SSH2_CIPHER_BLOWFISH_CBC:
-		return "blowfish-cbc(SSH2)";
-	case SSH2_CIPHER_AES128_CTR:
-		return "aes128-ctr(SSH2)";
-	case SSH2_CIPHER_AES192_CTR:
-		return "aes192-ctr(SSH2)";
-	case SSH2_CIPHER_AES256_CTR:
-		return "aes256-ctr(SSH2)";
-	case SSH2_CIPHER_ARCFOUR:
-		return "arcfour(SSH2)";
-	case SSH2_CIPHER_ARCFOUR128:
-		return "arcfour128(SSH2)";
-	case SSH2_CIPHER_ARCFOUR256:
-		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)";
-	case SSH2_CIPHER_CAMELLIA128_CBC:
-		return "camellia128-cbc(SSH2)";
-	case SSH2_CIPHER_CAMELLIA192_CBC:
-		return "camellia192-cbc(SSH2)";
-	case SSH2_CIPHER_CAMELLIA256_CBC:
-		return "camellia256-cbc(SSH2)";
-	case SSH2_CIPHER_CAMELLIA128_CTR:
-		return "camellia128-ctr(SSH2)";
-	case SSH2_CIPHER_CAMELLIA192_CTR:
-		return "camellia192-ctr(SSH2)";
-	case SSH2_CIPHER_CAMELLIA256_CTR:
-		return "camellia256-ctr(SSH2)";
-	case SSH2_CIPHER_AES128_GCM:
-		return "aes12****@opens*****(SSH2)";
-	case SSH2_CIPHER_AES256_GCM:
-		return "aes25****@opens*****(SSH2)";
-
-	default:
-		return NULL;
-	}
-}
-
 static void set_move_button_status(HWND dlg, int type, int up, int down)
 {
 	HWND cipherControl = GetDlgItem(dlg, type);
@@ -2690,7 +2427,7 @@
 
 	for (i = 0; pvar->settings.CipherOrder[i] != 0; i++) {
 		int cipher = pvar->settings.CipherOrder[i] - '0';
-		char *name = get_cipher_name(cipher);
+		char *name = get_listbox_cipher_name(cipher, pvar);
 
 		if (name != NULL) {
 			SendMessage(cipherControl, LB_ADDSTRING, 0, (LPARAM) name);
@@ -2732,7 +2469,7 @@
 			                  "<Host Keys below this line are disabled>");
 			name = pvar->ts->UIMsg;
 		} else {
-			name = get_ssh_keytype_name(index);
+			name = get_ssh2_hostkey_type_name(index);
 		}
 
 		if (name != NULL) {
@@ -2941,7 +2678,7 @@
 			buf[0] = 0;
 			SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf);
 			for (j = 0; j <= SSH_CIPHER_MAX; j++) {
-				char *cipher_name = get_cipher_name(j);
+				char *cipher_name = get_listbox_cipher_name(j, pvar);
 				if (cipher_name != NULL && strcmp(buf, cipher_name) == 0) {
 					break;
 				}
@@ -2995,7 +2732,7 @@
 			SendMessage(cipherControl, LB_GETTEXT, i, (LPARAM) buf);
 			for (j = 0;
 				j <= KEY_MAX
-				 && strcmp(buf, get_ssh_keytype_name(j)) != 0; j++) {
+				 && strcmp(buf, get_ssh2_hostkey_type_name(j)) != 0; j++) {
 			}
 			if (j <= KEY_MAX) {
 				buf2[buf2index] = '0' + j;
@@ -3538,141 +3275,6 @@
 }
 
 
-//
-// SSH1 3DES
-//
-/*
- * This is used by SSH1:
- *
- * What kind of triple DES are these 2 routines?
- *
- * Why is there a redundant initialization vector?
- *
- * If only iv3 was used, then, this would till effect have been
- * outer-cbc. However, there is also a private iv1 == iv2 which
- * perhaps makes differential analysis easier. On the other hand, the
- * private iv1 probably makes the CRC-32 attack ineffective. This is a
- * result of that there is no longer any known iv1 to use when
- * choosing the X block.
- */
-struct ssh1_3des_ctx
-{
-	EVP_CIPHER_CTX  *k1, *k2, *k3;
-};
-
-static int ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv, int enc)
-{
-	struct ssh1_3des_ctx *c;
-	u_char *k1, *k2, *k3;
-
-	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-		c = malloc(sizeof(*c));
-		c->k1 = EVP_CIPHER_CTX_new();
-		c->k2 = EVP_CIPHER_CTX_new();
-		c->k3 = EVP_CIPHER_CTX_new();
-		/*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/
-		EVP_CIPHER_CTX_set_app_data(ctx, c);
-	}
-	if (key == NULL)
-		return (1);
-	if (enc == -1)
-		enc = EVP_CIPHER_CTX_encrypting(ctx); // ctx->encrypt
-	k1 = k2 = k3 = (u_char *) key;
-	k2 += 8;
-	if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
-		if (enc)
-			k3 += 16;
-		else
-			k1 += 16;
-	}
-	if (EVP_CipherInit(c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
-		EVP_CipherInit(c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
-		EVP_CipherInit(c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
-			EVP_CIPHER_CTX_free(c->k1);
-			EVP_CIPHER_CTX_free(c->k2);
-			EVP_CIPHER_CTX_free(c->k3);
-			SecureZeroMemory(c, sizeof(*c));
-			free(c);
-			EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-			return (0);
-	}
-	return (1);
-}
-
-static int ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
-{
-	struct ssh1_3des_ctx *c;
-
-	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-		//error("ssh1_3des_cbc: no context");
-		return (0);
-	}
-	if (EVP_Cipher(c->k1, dest, (u_char *)src, len) == 0 ||
-		EVP_Cipher(c->k2, dest, dest, len) == 0 ||
-		EVP_Cipher(c->k3, dest, dest, len) == 0)
-		return (0);
-	return (1);
-}
-
-static int ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
-{
-	struct ssh1_3des_ctx *c;
-
-	if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-		EVP_CIPHER_CTX_free(c->k1);
-		EVP_CIPHER_CTX_free(c->k2);
-		EVP_CIPHER_CTX_free(c->k3);
-		SecureZeroMemory(c, sizeof(*c));
-		free(c);
-		EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-	}
-	return (1);
-}
-
-// \x89\xBA\x8BL\x8A֐\x94\x82͖\xA2\x8Eg\x97p\x81B
-void ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
-{
-	struct ssh1_3des_ctx *c;
-
-	if (len != 24)
-		//fatal("%s: bad 3des iv length: %d", __func__, len);
-		;
-
-	if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
-		//fatal("%s: no 3des context", __func__);
-		;
-
-	if (doset) {
-		//debug3("%s: Installed 3DES IV", __func__);
-		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k1), iv, 8);
-		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k2), iv + 8, 8);
-		memcpy(EVP_CIPHER_CTX_iv_noconst(c->k3), iv + 16, 8);
-	} else {
-		//debug3("%s: Copying 3DES IV", __func__);
-		memcpy(iv, EVP_CIPHER_CTX_iv(c->k1), 8);
-		memcpy(iv + 8, EVP_CIPHER_CTX_iv(c->k2), 8);
-		memcpy(iv + 16, EVP_CIPHER_CTX_iv(c->k3), 8);
-	}
-}
-
-const EVP_CIPHER *evp_ssh1_3des(void)
-{
-	static EVP_CIPHER *p = NULL;
-
-	if (p == NULL) {
-		p = EVP_CIPHER_meth_new(NID_undef, /*block_size*/8, /*key_len*/16);
-		/*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/
-	}
-	if (p) {
-		EVP_CIPHER_meth_set_iv_length(p, 0);
-		EVP_CIPHER_meth_set_init(p, ssh1_3des_init);
-		EVP_CIPHER_meth_set_cleanup(p, ssh1_3des_cleanup);
-		EVP_CIPHER_meth_set_do_cipher(p, ssh1_3des_cbc);
-		EVP_CIPHER_meth_set_flags(p, EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH);
-	}
-	return (p);
-}
-
 static void ssh_make_comment(char *comment, int maxlen)
 {
 	char user[UNLEN + 1], host[128];
@@ -4032,7 +3634,7 @@
 // based on OpenSSH 6.5:key_save_private(), key_private_to_blob2()
 static void save_bcrypt_private_key(char *passphrase, char *filename, char *comment, HWND dlg, PTInstVar pvar, int rounds)
 {
-	SSH2Cipher *cipher = NULL;
+	const struct ssh2cipher *cipher = NULL;
 	char *ciphername = DEFAULT_CIPHERNAME;
 	buffer_t *b = NULL;
 	buffer_t *kdf = NULL;
@@ -4630,7 +4232,7 @@
 				case KEY_ECDSA256: // ECDSA
 				case KEY_ECDSA384:
 				case KEY_ECDSA521:
-					keyname = get_ssh_keytype_name(public_key.type);
+					keyname = get_ssh2_hostkey_type_name(public_key.type);
 					buffer_put_string(b, keyname, strlen(keyname));
 					s = curve_keytype_to_name(public_key.type);
 					buffer_put_string(b, s, strlen(s));
@@ -4639,7 +4241,7 @@
 					break;
 
 				case KEY_ED25519:
-					keyname = get_ssh_keytype_name(public_key.type);
+					keyname = get_ssh2_hostkey_type_name(public_key.type);
 					buffer_put_cstring(b, keyname);
 					buffer_put_string(b, public_key.ed25519_pk, ED25519_PK_SZ);
 					break;

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.h
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.h	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.h	2021-04-17 08:36:59 UTC (rev 9210)
@@ -74,6 +74,11 @@
 #include "ssh.h"
 #include "auth.h"
 #include "crypt.h"
+#include "cipher.h"
+#include "comp.h"
+#include "kex.h"
+#include "hostkey.h"
+#include "key.h"
 #include "hosts.h"
 #include "fwd.h"
 
@@ -268,8 +273,8 @@
 	buffer_t *peer_kex;
 	kex_algorithm kex_type; // KEX algorithm
 	ssh_keytype hostkey_type;
-	SSH2Cipher *ciphers[MODE_MAX];
-	SSH2Mac *macs[MODE_MAX];
+	const struct ssh2cipher *ciphers[MODE_MAX];
+	const struct SSH2Mac *macs[MODE_MAX];
 	compression_type ctos_compression;
 	compression_type stoc_compression;
 	int we_need;

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj	2021-04-17 08:36:59 UTC (rev 9210)
@@ -153,7 +153,10 @@
     <ClCompile Include="auth.c" />
     <ClCompile Include="buffer.c" />
     <ClCompile Include="chacha.c" />
+    <ClCompile Include="cipher.c" />
+    <ClCompile Include="cipher-3des1.c" />
     <ClCompile Include="cipher-ctr.c" />
+    <ClCompile Include="comp.c" />
     <ClCompile Include="crypt.c" />
     <ClCompile Include="dns.c" />
     <ClCompile Include="ed25519.c" />
@@ -168,13 +171,16 @@
     <ClCompile Include="fwd-socks.c" />
     <ClCompile Include="fwd.c" />
     <ClCompile Include="fwdui.c" />
+    <ClCompile Include="hostkey.c" />
     <ClCompile Include="hosts.c" />
     <ClCompile Include="kex.c" />
     <ClCompile Include="key.c" />
     <ClCompile Include="keyfiles.c" />
+    <ClCompile Include="mac.c" />
     <ClCompile Include="pkt.c" />
     <ClCompile Include="sftp.c" />
     <ClCompile Include="ssh.c" />
+    <ClCompile Include="ssherr.c" />
     <ClCompile Include="ttxssh.c" />
     <ClCompile Include="util.c" />
     <ClCompile Include="x11util.c" />
@@ -186,6 +192,7 @@
     <ClInclude Include="buffer.h" />
     <ClInclude Include="chacha.h" />
     <ClInclude Include="cipher.h" />
+    <ClInclude Include="comp.h" />
     <ClInclude Include="config.h" />
     <ClInclude Include="crypt.h" />
     <ClInclude Include="dns.h" />
@@ -197,14 +204,17 @@
     <ClInclude Include="fwd-socks.h" />
     <ClInclude Include="fwd.h" />
     <ClInclude Include="fwdui.h" />
+    <ClInclude Include="hostkey.h" />
     <ClInclude Include="hosts.h" />
     <ClInclude Include="kex.h" />
     <ClInclude Include="key.h" />
     <ClInclude Include="keyfiles.h" />
+    <ClInclude Include="mac.h" />
     <ClInclude Include="pkt.h" />
     <ClInclude Include="resource.h" />
     <ClInclude Include="sftp.h" />
     <ClInclude Include="ssh.h" />
+    <ClInclude Include="ssherr.h" />
     <ClInclude Include="ttxssh-version.h" />
     <ClInclude Include="ttxssh.h" />
     <ClInclude Include="util.h" />

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters	2021-04-17 08:36:59 UTC (rev 9210)
@@ -13,9 +13,18 @@
     <ClCompile Include="chacha.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="cipher.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
+    <ClCompile Include="cipher-3des1.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="cipher-ctr.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="comp.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="crypt.c">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -58,6 +67,9 @@
     <ClCompile Include="fwdui.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="hostkey.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="hosts.c">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -70,6 +82,9 @@
     <ClCompile Include="keyfiles.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="mac.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="..\matcher\matcher.c">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -82,6 +97,9 @@
     <ClCompile Include="ssh.c">
       <Filter>Source Files</Filter>
     </ClCompile>
+    <ClCompile Include="ssherr.c">
+      <Filter>Source Files</Filter>
+    </ClCompile>
     <ClCompile Include="ttxssh.c">
       <Filter>Source Files</Filter>
     </ClCompile>
@@ -144,6 +162,9 @@
     <ClInclude Include="config.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="comp.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="crypt.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -171,6 +192,9 @@
     <ClInclude Include="fwdui.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="hostkey.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="hosts.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -183,6 +207,9 @@
     <ClInclude Include="keyfiles.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="mac.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="pkt.h">
       <Filter>Header Files</Filter>
     </ClInclude>
@@ -192,6 +219,9 @@
     <ClInclude Include="ssh.h">
       <Filter>Header Files</Filter>
     </ClInclude>
+    <ClInclude Include="ssherr.h">
+      <Filter>Header Files</Filter>
+    </ClInclude>
     <ClInclude Include="util.h">
       <Filter>Header Files</Filter>
     </ClInclude>

Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v8.vcproj
===================================================================
--- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v8.vcproj	2021-04-17 06:32:42 UTC (rev 9209)
+++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ttxssh.v8.vcproj	2021-04-17 08:36:59 UTC (rev 9210)
@@ -240,6 +240,10 @@
 				>
 			</File>
 			<File
+				RelativePath="comp.h"
+				>
+			</File>
+			<File
 				RelativePath="config.h"
 				>
 			</File>
@@ -284,6 +288,10 @@
 				>
 			</File>
 			<File
+				RelativePath="hostkey.h"
+				>
+			</File>
+			<File
 				RelativePath="hosts.h"
 				>
 			</File>
@@ -300,6 +308,10 @@
 				>
 			</File>
 			<File
+				RelativePath="mac.h"
+				>
+			</File>
+			<File
 				RelativePath="pkt.h"
 				>
 			</File>
@@ -316,6 +328,10 @@
 				>
 			</File>
 			<File
+				RelativePath="ssherr.h"
+				>
+			</File>
+			<File
 				RelativePath="ttxssh-version.h"
 				>
 			</File>
@@ -352,6 +368,14 @@
 				>
 			</File>
 			<File
+				RelativePath="cipher.c"
+				>
+			</File>
+			<File
+				RelativePath="cipher-3des1.c"
+				>
+			</File>
+			<File
 				RelativePath="cipher-ctr.c"
 				>
 			</File>
@@ -360,6 +384,10 @@
 				>
 			</File>
 			<File
+				RelativePath="comp.c"
+				>
+			</File>
+			<File
 				RelativePath="crypt.c"
 				>
 			</File>
@@ -428,6 +456,10 @@
 				>
 			</File>
 			<File
+				RelativePath="hostkey.c"
+				>
+			</File>
+			<File
 				RelativePath="hosts.c"
 				>
 			</File>
@@ -444,6 +476,10 @@
 				>
 			</File>
 			<File
+				RelativePath="mac.c"
+				>
+			</File>
+			<File
 				RelativePath="..\matcher\matcher.c"
 				>
 			</File>
@@ -460,6 +496,10 @@
 				>
 			</File>
 			<File
+				RelativePath="ssherr.c"
+				>
+			</File>
+			<File
 				RelativePath="..\..\teraterm\common\tipwin.cpp"
 				>
 			</File>


Ttssh2-commit メーリングリストの案内
Back to archive index