[Ttssh2-commit] [6969] OpenSSH の EtM 方式の MAC に対応。#31495

Back to archive index

scmno****@osdn***** scmno****@osdn*****
2017年 11月 2日 (木) 20:37:41 JST


Revision: 6969
          http://sourceforge.jp/projects/ttssh2/scm/svn/commits/6969
Author:   doda
Date:     2017-11-02 20:37:41 +0900 (Thu, 02 Nov 2017)
Log Message:
-----------
OpenSSH の EtM 方式の MAC に対応。#31495

以下の MAC 方式に対応。
  ・hmac-****@opens*****hmac-****@opens*****hmac-****@opens*****hmac-****@opens***** (*1)
  ・hmac-****@opens***** (*1, *2)
  ・hmac-****@opens***** (*1, *3)
  ・hmac-****@opens***** (*1, *3)

検討事項:
  ・*1 の方式は現在のOpenSSHではデフォルトでは使わないようになっているが、
    サポートする価値はある?  (サーバ: 6.7以降, クライアント:7.2以降)
  ・*2 の ripemd160 は OpenSSH 7.6 ではサポートがはずされて使えなくなった。
    OpenSSH 7.5 以前なら(設定すれば)使えるが、サポートする価値はある?
  ・*3 の 96bit truncate な MAC は優先度を NONE より下にしてデフォルトでは
    使わないようにした。今時 96bit truncate な MAC をサポートする価値ある?
  ・OpenSSH では EtM な MAC を優先するようになっており、ttssh もそれに
    習って順番を決めた。しかしアップグレードインストールでは末尾に追加
    される為、優先度が低くなる。ア
    ップグレー時にも優先度を高くする方法はないか?

Ticket Links:
------------
    http://sourceforge.jp/projects/ttssh2/tracker/detail/31495

Modified Paths:
--------------
    trunk/doc/en/html/about/history.html
    trunk/doc/ja/html/about/history.html
    trunk/installer/release/TERATERM.INI
    trunk/ttssh2/ttxssh/pkt.c
    trunk/ttssh2/ttxssh/ssh.c
    trunk/ttssh2/ttxssh/ssh.h
    trunk/ttssh2/ttxssh/ttxssh.c

-------------- next part --------------
Modified: trunk/doc/en/html/about/history.html
===================================================================
--- trunk/doc/en/html/about/history.html	2017-11-02 11:37:37 UTC (rev 6968)
+++ trunk/doc/en/html/about/history.html	2017-11-02 11:37:41 UTC (rev 6969)
@@ -2966,6 +2966,16 @@
           <li>added the <a href="../setup/teraterm-com.html#TerminalSpeed">TerminalSpeed</a> entry in the teraterm.ini file. The default is 38400.</li>
           <li>The default value of the terminal speed notifies to the server is changed to 38400 bps.</li>
         </ul></li>
+      <li>added support for SSH2 MAC algorithms:</li>
+        <ul>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+        </ul></li>
     </ul>
   </li>
 </ul>

Modified: trunk/doc/ja/html/about/history.html
===================================================================
--- trunk/doc/ja/html/about/history.html	2017-11-02 11:37:37 UTC (rev 6968)
+++ trunk/doc/ja/html/about/history.html	2017-11-02 11:37:41 UTC (rev 6969)
@@ -2972,6 +2972,16 @@
           <li>teraterm.ini \x82\xC9 <a href="../setup/teraterm-com.html#TerminalSpeed">TerminalSpeed</a> \x83G\x83\x93\x83g\x83\x8A\x82\xF0\x92lj\xC1\x82\xB5\x82\xBD\x81B\x83f\x83t\x83H\x83\x8B\x83g\x82\xCD38400\x81B</li>
           <li>\x83T\x81[\x83o\x82ɒʒm\x82\xB7\x82\xE9\x92[\x96\x96\x91\xAC\x93x\x82̃f\x83t\x83H\x83\x8B\x83g\x82\xF0 38400bps \x82ɕύX\x82\xB5\x82\xBD\x81B</li>
         </ul></li>
+      <li>SSH2 \x82\xCC MAC \x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82Ƃ\xB5\x82Ĉȉ\xBA\x82\xF0\x83T\x83|\x81[\x83g\x82\xB5\x82\xBD\x81B
+        <ul>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+          <li>hmac-****@opens*****</li>
+        </ul></li>
     </ul>
   </li>
 </ul>

Modified: trunk/installer/release/TERATERM.INI
===================================================================
--- trunk/installer/release/TERATERM.INI	2017-11-02 11:37:37 UTC (rev 6968)
+++ trunk/installer/release/TERATERM.INI	2017-11-02 11:37:41 UTC (rev 6969)
@@ -836,6 +836,13 @@
 ;  5...h****@opens*****
 ;  6...hmac-sha2-256
 ;  8...hmac-sha2-512
+;  :...hm****@opens*****
+;  ;...hm****@opens*****
+;  <...hm****@opens*****
+;  =...hm****@opens*****
+;  >...hm****@opens*****
+;  ?...hm****@opens*****
+;  @...hm****@opens*****
 ;  0...below this line are disabled.
 MacOrder=86152034
 

Modified: trunk/ttssh2/ttxssh/pkt.c
===================================================================
--- trunk/ttssh2/ttxssh/pkt.c	2017-11-02 11:37:37 UTC (rev 6968)
+++ trunk/ttssh2/ttxssh/pkt.c	2017-11-02 11:37:41 UTC (rev 6969)
@@ -181,9 +181,13 @@
 			uint32 padding;
 			uint32 pktsize;
 			uint32 total_packet_size;
+			struct Mac *mac = &pvar->ssh2_keys[MODE_IN].mac;
+			int etm;
 
+			etm = mac && mac->enabled && mac->etm;
+
 			// \x88Í\x86\x89\xBB\x83p\x83P\x83b\x83g\x82̈ꕔ\x82𕜍\x86\x89\xBB\x82\xB7\x82\xE9\x81B
-			if (!pvar->pkt_state.predecrypted_packet) {
+			if (!pvar->pkt_state.predecrypted_packet && !etm) {
 				SSH_predecrpyt_packet(pvar, data);
 				pvar->pkt_state.predecrypted_packet = TRUE;
 			}
@@ -196,7 +200,12 @@
 			} else {
 				// SSH2\x82̃p\x83P\x83b\x83g\x82͐擪\x82\xC9 packet-size(4)+padding(1)+type(1) \x82\xAA\x91\xB1\x82\xAD\x81B
 				pktsize = get_uint32_MSBfirst(data);
-				padding = (unsigned char) data[4];
+				if (etm) {
+					padding = 0;
+				}
+				else {
+					padding = (unsigned char) data[4];
+				}
 			}
 
 			// \x83p\x83P\x83b\x83g(TCP\x83y\x83C\x83\x8D\x81[\x83h)\x82̑S\x91̂̃T\x83C\x83Y\x82́ASSH\x83y\x83C\x83\x8D\x81[\x83h\x81{4\x81i\x81{MAC\x81j\x82ƂȂ\xE9\x81B
@@ -209,7 +218,7 @@
 					SSH_handle_packet1(pvar, data, pktsize, padding);
 				}
 				else {
-					SSH_handle_packet2(pvar, data, pktsize, padding);
+					SSH_handle_packet2(pvar, data, pktsize, padding, etm);
 				}
 				pvar->pkt_state.predecrypted_packet = FALSE;
 

Modified: trunk/ttssh2/ttxssh/ssh.c
===================================================================
--- trunk/ttssh2/ttxssh/ssh.c	2017-11-02 11:37:37 UTC (rev 6968)
+++ trunk/ttssh2/ttxssh/ssh.c	2017-11-02 11:37:41 UTC (rev 6969)
@@ -774,21 +774,33 @@
 	return pvar->ssh_state.payload[-1];
 }
 
-static int prep_packet_ssh2(PTInstVar pvar, char *data, int len, int padding)
+static int prep_packet_ssh2(PTInstVar pvar, char *data, int len, int padding, int etm)
 {
-	int already_decrypted = get_predecryption_amount(pvar);
-
 	pvar->ssh_state.payload = data + 4;
 	pvar->ssh_state.payloadlen = len;
 
-	CRYPT_decrypt(pvar, data + already_decrypted, (4 + len) - already_decrypted);
+	if (etm) {
+		if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {
+			UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");
+			notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
+			return SSH_MSG_NONE;
+		}
 
-	if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {
-		UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");
-		notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
-		return SSH_MSG_NONE;
+		CRYPT_decrypt(pvar, data + 4, len);
+		padding = (unsigned int) data[4];
 	}
+	else {
+		int already_decrypted = get_predecryption_amount(pvar);
 
+		CRYPT_decrypt(pvar, data + already_decrypted, (4 + len) - already_decrypted);
+
+		if (!CRYPT_verify_receiver_MAC(pvar, pvar->ssh_state.receiver_sequence_number, data, len + 4, data + len + 4)) {
+			UTIL_get_lang_msg("MSG_SSH_CORRUPTDATA_ERROR", pvar, "Detected corrupted data; connection terminating.");
+			notify_fatal_error(pvar, pvar->ts->UIMsg, TRUE);
+			return SSH_MSG_NONE;
+		}
+	}
+
 	pvar->ssh_state.payload++;
 	pvar->ssh_state.payloadlen -= padding + 1;
 
@@ -989,6 +1001,8 @@
 		unsigned int encryption_size;
 		unsigned int padding;
 		BOOL ret;
+		struct Mac *mac = &pvar->ssh2_keys[MODE_OUT].mac;
+		int aadlen = 0;
 
 		/*
 		 \x83f\x81[\x83^\x8D\\x91\xA2
@@ -1041,14 +1055,18 @@
 			block_size = 8;
 		}
 
-		encryption_size = 4 + 1 + len;
+		if (mac && mac->etm) {
+			aadlen = 4;
+		}
+
+		encryption_size = 4 - aadlen + 1 + len;
 		padding = block_size - (encryption_size % block_size);
 		if (padding < 4)
 			padding += block_size;
 		encryption_size += padding;
-		set_uint32(data, encryption_size - 4);
+		set_uint32(data, encryption_size - 4 + aadlen);
 		data[4] = (unsigned char) padding;
-		data_length = encryption_size + CRYPT_get_sender_MAC_size(pvar);
+		data_length = encryption_size;
 		if (msg) {
 			// \x83p\x83P\x83b\x83g\x88\xB3\x8Fk\x82̏ꍇ\x81A\x83o\x83b\x83t\x83@\x82\xF0\x8Ag\x92\xA3\x82\xB7\x82\xE9\x81B(2011.6.10 yutaka)
 			buffer_append_space(msg, padding + EVP_MAX_MD_SIZE);
@@ -1058,16 +1076,33 @@
 
 		//if (pvar->ssh_state.outbuflen <= 7 + data_length) *(int *)0 = 0;
 		CRYPT_set_random_data(pvar, data + 5 + len, padding);
-		ret = CRYPT_build_sender_MAC(pvar,
-		                             pvar->ssh_state.sender_sequence_number,
-		                             data, encryption_size,
-		                             data + encryption_size);
-		if (ret == FALSE) { // MAC\x82\xAA\x82܂\xBE\x90ݒ肳\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x8Fꍇ
-			data_length = encryption_size;
+
+		if (aadlen == 0) {
+			ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number,
+			                             data, encryption_size, data + encryption_size);
+			if (ret) {
+				data_length += CRYPT_get_sender_MAC_size(pvar);
+//				data[encryption_size + 5] = 0;
+			}
 		}
 
 		// \x83p\x83P\x83b\x83g\x82\xF0\x88Í\x86\x89\xBB\x82\xB7\x82\xE9\x81BMAC\x88ȍ~\x82͈Í\x86\x89\xBB\x91ΏۊO\x81B
-		CRYPT_encrypt(pvar, data, encryption_size);
+		CRYPT_encrypt(pvar, data + aadlen, encryption_size);
+
+		if (aadlen) {
+			int maclen;
+			encryption_size += aadlen;
+			ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number,
+			                             data, encryption_size, data + encryption_size);
+			if (ret) {
+				maclen = CRYPT_get_sender_MAC_size(pvar);
+				data_length = encryption_size + maclen;
+			}
+			logprintf(LOG_LEVEL_ERROR, __FUNCTION__
+				": EtM test. aadlen:%d, enclen:%d, pad:%d, datalen:%d, maclen:%d",
+				aadlen, encryption_size, padding, data_length, maclen);
+		}
+
 	}
 
 	send_packet_blocking(pvar, data, data_length);
@@ -2035,7 +2070,6 @@
 	}
 }
 
-
 void SSH_handle_packet1(PTInstVar pvar, char *data, int len, int padding)
 {
 	unsigned char message = prep_packet_ssh1(pvar, data, len, padding);
@@ -2059,9 +2093,9 @@
 	}
 }
 
-void SSH_handle_packet2(PTInstVar pvar, char *data, int len, int padding)
+void SSH_handle_packet2(PTInstVar pvar, char *data, int len, int padding, int etm)
 {
-	unsigned char message = prep_packet_ssh2(pvar, data, len, padding);
+	unsigned char message = prep_packet_ssh2(pvar, data, len, padding, etm);
 
 	// SSH\x82̃\x81\x83b\x83Z\x81[\x83W\x83^\x83C\x83v\x82\xF0\x83`\x83F\x83b\x83N
 	if (message != SSH_MSG_NONE) {
@@ -4168,6 +4202,21 @@
 	return bits;
 }
 
+int get_ssh2_mac_etm(hmac_type type)
+{
+	ssh2_mac_t *ptr = ssh2_macs;
+	int etm;
+
+	while (ptr->name != NULL) {
+		if (type == ptr->type) {
+			etm = ptr->etm;
+			break;
+		}
+		ptr++;
+	}
+	return etm;
+}
+
 char* get_ssh2_comp_name(compression_type type)
 {
 	ssh2_comp_t *ptr = ssh2_comps;
@@ -4701,6 +4750,7 @@
 		if (get_ssh2_mac_truncatebits(val) != 0) {
 			current_keys[mode].mac.mac_len = get_ssh2_mac_truncatebits(val) / 8;
 		}
+		current_keys[mode].mac.etm = get_ssh2_mac_etm(val);
 
 		// \x83L\x81[\x83T\x83C\x83Y\x82ƃu\x83\x8D\x83b\x83N\x83T\x83C\x83Y\x82\xE0\x82\xB1\x82\xB1\x82Őݒ肵\x82Ă\xA8\x82\xAD (2004.11.7 yutaka)
 		if (ctos == 1) {

Modified: trunk/ttssh2/ttxssh/ssh.h
===================================================================
--- trunk/ttssh2/ttxssh/ssh.h	2017-11-02 11:37:37 UTC (rev 6968)
+++ trunk/ttssh2/ttxssh/ssh.h	2017-11-02 11:37:41 UTC (rev 6969)
@@ -465,6 +465,13 @@
 	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_UNKNOWN,
 	HMAC_MAX = HMAC_UNKNOWN,
 } hmac_type;
@@ -474,19 +481,25 @@
 	char *name;
 	const EVP_MD *(*evp_md)(void);
 	int truncatebits;
+	int etm;
 } ssh2_mac_t;
 
 static ssh2_mac_t ssh2_macs[] = {
-	{HMAC_SHA1,        "hmac-sha1",                  EVP_sha1,      0},  // RFC4253
-	{HMAC_MD5,         "hmac-md5",                   EVP_md5,       0},  // RFC4253
-	{HMAC_SHA1_96,     "hmac-sha1-96",               EVP_sha1,      96}, // RFC4253
-	{HMAC_MD5_96,      "hmac-md5-96",                EVP_md5,       96}, // RFC4253
-	{HMAC_RIPEMD160,   "hmac-****@opens*****", EVP_ripemd160, 0},
-	{HMAC_SHA2_256,    "hmac-sha2-256",              EVP_sha256,    0},  // RFC6668
-//	{HMAC_SHA2_256_96, "hmac-sha2-256-96",           EVP_sha256,    96}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06
-	{HMAC_SHA2_512,    "hmac-sha2-512",              EVP_sha512,    0},  // RFC6668
-//	{HMAC_SHA2_512_96, "hmac-sha2-512-96",           EVP_sha512,    96}, // draft-dbider-sha2-mac-for-ssh-05, deleted at 06
-	{HMAC_NONE,        NULL,                         NULL,          0},
+	{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_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_NONE,         NULL,                            NULL,          0,  0},
 };
 
 
@@ -526,6 +539,7 @@
 	int             mac_len; 
 	u_char          *key;
 	int             key_len;
+	int		etm;
 };
 
 struct Comp {
@@ -697,7 +711,7 @@
    'data' points to the start of the packet data (the length field)
 */
 void SSH_handle_packet1(PTInstVar pvar, char *data, int len, int padding);
-void SSH_handle_packet2(PTInstVar pvar, char *data, int len, int padding);
+void SSH_handle_packet2(PTInstVar pvar, char *data, int len, int padding, int etm);
 void SSH_notify_win_size(PTInstVar pvar, int cols, int rows);
 void SSH_notify_user_name(PTInstVar pvar);
 void SSH_notify_cred(PTInstVar pvar);

Modified: trunk/ttssh2/ttxssh/ttxssh.c
===================================================================
--- trunk/ttssh2/ttxssh/ttxssh.c	2017-11-02 11:37:37 UTC (rev 6968)
+++ trunk/ttssh2/ttxssh/ttxssh.c	2017-11-02 11:37:41 UTC (rev 6969)
@@ -348,12 +348,19 @@
 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,



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