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,