Revision: 9254 https://osdn.net/projects/ttssh2/scm/svn/commits/9254 Author: nmaya Date: 2021-05-19 23:11:12 +0900 (Wed, 19 May 2021) Log Message: ----------- SSH2 暗号化方式 chach****@opens***** をサポート merge from branches/ssh_chacha20poly1305 r9209, r9210, r9211, r9212, r9217, r9229, r9248, r9249, r9250, r9251, r9252, r9253 Revision Links: -------------- https://osdn.net/projects/ttssh2/scm/svn/commits/9209 https://osdn.net/projects/ttssh2/scm/svn/commits/9210 https://osdn.net/projects/ttssh2/scm/svn/commits/9211 https://osdn.net/projects/ttssh2/scm/svn/commits/9212 https://osdn.net/projects/ttssh2/scm/svn/commits/9217 https://osdn.net/projects/ttssh2/scm/svn/commits/9229 https://osdn.net/projects/ttssh2/scm/svn/commits/9248 https://osdn.net/projects/ttssh2/scm/svn/commits/9249 https://osdn.net/projects/ttssh2/scm/svn/commits/9250 https://osdn.net/projects/ttssh2/scm/svn/commits/9251 https://osdn.net/projects/ttssh2/scm/svn/commits/9252 https://osdn.net/projects/ttssh2/scm/svn/commits/9253 Modified Paths: -------------- branches/4-stable/doc/en/html/about/history.html branches/4-stable/doc/en/html/menu/setup-ssh.html branches/4-stable/doc/ja/html/about/history.html branches/4-stable/doc/ja/html/menu/setup-ssh.html branches/4-stable/installer/release/TERATERM.INI branches/4-stable/ttssh2/ttxssh/CMakeLists.txt branches/4-stable/ttssh2/ttxssh/auth.c branches/4-stable/ttssh2/ttxssh/auth.h branches/4-stable/ttssh2/ttxssh/cipher.h branches/4-stable/ttssh2/ttxssh/crypt.c branches/4-stable/ttssh2/ttxssh/hosts.c branches/4-stable/ttssh2/ttxssh/kex.c branches/4-stable/ttssh2/ttxssh/kex.h branches/4-stable/ttssh2/ttxssh/key.c branches/4-stable/ttssh2/ttxssh/key.h branches/4-stable/ttssh2/ttxssh/keyfiles.c branches/4-stable/ttssh2/ttxssh/pkt.c branches/4-stable/ttssh2/ttxssh/ssh.c branches/4-stable/ttssh2/ttxssh/ssh.h branches/4-stable/ttssh2/ttxssh/ttxssh.c branches/4-stable/ttssh2/ttxssh/ttxssh.h branches/4-stable/ttssh2/ttxssh/ttxssh.v16.vcxproj branches/4-stable/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters branches/4-stable/ttssh2/ttxssh/ttxssh.v8.vcproj Added Paths: ----------- branches/4-stable/ttssh2/ttxssh/cipher-3des1.c branches/4-stable/ttssh2/ttxssh/cipher-chachapoly-libcrypto.c branches/4-stable/ttssh2/ttxssh/cipher-chachapoly.h branches/4-stable/ttssh2/ttxssh/cipher.c branches/4-stable/ttssh2/ttxssh/comp.c branches/4-stable/ttssh2/ttxssh/comp.h branches/4-stable/ttssh2/ttxssh/hostkey.c branches/4-stable/ttssh2/ttxssh/hostkey.h branches/4-stable/ttssh2/ttxssh/mac.c branches/4-stable/ttssh2/ttxssh/mac.h branches/4-stable/ttssh2/ttxssh/poly1305.c branches/4-stable/ttssh2/ttxssh/poly1305.h branches/4-stable/ttssh2/ttxssh/ssherr.c branches/4-stable/ttssh2/ttxssh/ssherr.h Property Changed: ---------------- branches/4-stable/ branches/4-stable/TTProxy/ branches/4-stable/TTXKanjiMenu/ branches/4-stable/TTXSamples/ branches/4-stable/cygterm/ branches/4-stable/teraterm/ branches/4-stable/ttpmenu/ -------------- next part -------------- Index: branches/4-stable =================================================================== --- branches/4-stable 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable 2021-05-19 14:11:12 UTC (rev 9254) Property changes on: branches/4-stable ___________________________________________________________________ Modified: svn:mergeinfo ## -4,6 +4,7 ## /branches/openssl_1_1_1_v3:8258,8264-8265 /branches/portfwd_memleak:7732,7736-7737,7764 /branches/serial_port_improved:8119,8140-8141,8144,8150,8158-8160,8163,8170-8172,8183,8185,8204,8209,8212-8215 +/branches/ssh_chacha20poly1305:9209-9253 /branches/ssh_ed25519:5495-5544 /branches/ttproxy_improved:8041,8055-8056 /branches/ttssh_improved:8027,8036,8040,8044,8053-8054,8058,8060,8063,8081,8085 Index: branches/4-stable/TTProxy =================================================================== --- branches/4-stable/TTProxy 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/TTProxy 2021-05-19 14:11:12 UTC (rev 9254) Property changes on: branches/4-stable/TTProxy ___________________________________________________________________ Modified: svn:mergeinfo ## -1,5 +1,6 ## /branches/openssl_1_1_1_v2/TTProxy:7785-7786,7788-7808,7861-7863,7898,7900,7902-7903,7909,7924,7934,7954-7957,7959,7973,7975,7979-7980 /branches/openssl_1_1_1_v3/TTProxy:8258 +/branches/ssh_chacha20poly1305/TTProxy:9209-9253 /branches/ttproxy_improved/TTProxy:8041,8055-8056 /branches/ttssh_improved/TTProxy:8040 /branches/vs2015_warn/TTProxy:6194-6285 Index: branches/4-stable/TTXKanjiMenu =================================================================== --- branches/4-stable/TTXKanjiMenu 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/TTXKanjiMenu 2021-05-19 14:11:12 UTC (rev 9254) Property changes on: branches/4-stable/TTXKanjiMenu ___________________________________________________________________ Modified: svn:mergeinfo ## -1,2 +1,3 ## +/branches/ssh_chacha20poly1305/TTXKanjiMenu:9209-9253 /branches/vs2015_warn/TTXKanjiMenu:6194-6285 /trunk/TTXKanjiMenu:8867 \ No newline at end of property Index: branches/4-stable/TTXSamples =================================================================== --- branches/4-stable/TTXSamples 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/TTXSamples 2021-05-19 14:11:12 UTC (rev 9254) Property changes on: branches/4-stable/TTXSamples ___________________________________________________________________ Modified: svn:mergeinfo ## -1,2 +1,3 ## +/branches/ssh_chacha20poly1305/TTXSamples:9209-9253 /branches/vs2015_warn/TTXSamples:6194-6285 /trunk/TTXSamples:8867 \ No newline at end of property Index: branches/4-stable/cygterm =================================================================== --- branches/4-stable/cygterm 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/cygterm 2021-05-19 14:11:12 UTC (rev 9254) Property changes on: branches/4-stable/cygterm ___________________________________________________________________ Modified: svn:mergeinfo ## -1,2 +1,3 ## /branches/openssl_1_1_1_v3/cygterm:8284 +/branches/ssh_chacha20poly1305/cygterm:9209-9253 /trunk/cygterm:8867 \ No newline at end of property Modified: branches/4-stable/doc/en/html/about/history.html =================================================================== --- branches/4-stable/doc/en/html/about/history.html 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/doc/en/html/about/history.html 2021-05-19 14:11:12 UTC (rev 9254) @@ -3278,11 +3278,11 @@ <h3 id="ttssh_2.92">2021.xx.xx (Ver 2.92)</h3> <ul class="history"> - <!-- li>Changes + <li>Changes <ul> - <li></li> + <li>added chach****@opens***** symmetric key cipher algorithm for SSH2 protocol.</li> </ul> - </li --> + </li> <li>Bug fixes <ul> Modified: branches/4-stable/doc/en/html/menu/setup-ssh.html =================================================================== --- branches/4-stable/doc/en/html/menu/setup-ssh.html 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/doc/en/html/menu/setup-ssh.html 2021-05-19 14:11:12 UTC (rev 9254) @@ -23,14 +23,14 @@ <td>not RFC5647, PROTOCOL of OpenSSH</td> </tr> <tr> - <td>aes12****@opens*****</td> - <td>not RFC5647, PROTOCOL of OpenSSH</td> - </tr> - <tr> <td>camellia256-ctr</td> <td>draft-kanno-secsh-camellia-02</td> </tr> <tr> + <td>chach****@opens*****</td> + <td>PROTOCOL.chacha20poly1305 of OpenSSH</td> + </tr> + <tr> <td>aes256-ctr</td> <td>RFC4344</td> </tr> @@ -59,6 +59,10 @@ <td>RFC4253</td> </tr> <tr> + <td>aes12****@opens*****</td> + <td>not RFC5647, PROTOCOL of OpenSSH</td> + </tr> + <tr> <td>camellia128-ctr</td> <td>draft-kanno-secsh-camellia-02</td> </tr> @@ -116,11 +120,11 @@ </tr> <tr> <td>Blowfish(SSH1)</td> - <td></td> + <td></td> </tr> <tr> <td>DES(SSH1)</td> - <td></td> + <td></td> </tr> </table> </dd> Modified: branches/4-stable/doc/ja/html/about/history.html =================================================================== --- branches/4-stable/doc/ja/html/about/history.html 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/doc/ja/html/about/history.html 2021-05-19 14:11:12 UTC (rev 9254) @@ -3284,11 +3284,11 @@ <h3 id="ttssh_2.92">2021.xx.xx (Ver 2.92)</h3> <ul class="history"> - <!-- li>\x95ύX + <li>\x95ύX <ul> - <li></a> + <li>SSH2 \x82̋\xA4\x92ʌ\xAE\x88Í\x86\x95\xFB\x8E\xAE\x82\xC9 chach****@opens***** \x82\xF0\x92lj\xC1\x82\xB5\x82\xBD\x81B</li> </ul> - </li --> + </li> <li>\x83o\x83O\x8FC\x90\xB3 <ul> Modified: branches/4-stable/doc/ja/html/menu/setup-ssh.html =================================================================== --- branches/4-stable/doc/ja/html/menu/setup-ssh.html 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/doc/ja/html/menu/setup-ssh.html 2021-05-19 14:11:12 UTC (rev 9254) @@ -23,14 +23,14 @@ <td>not RFC5647, PROTOCOL of OpenSSH</td> </tr> <tr> - <td>aes12****@opens*****</td> - <td>not RFC5647, PROTOCOL of OpenSSH</td> - </tr> - <tr> <td>camellia256-ctr</td> <td>draft-kanno-secsh-camellia-02</td> </tr> <tr> + <td>chach****@opens*****</td> + <td>PROTOCOL.chacha20poly1305 of OpenSSH</td> + </tr> + <tr> <td>aes256-ctr</td> <td>RFC4344</td> </tr> @@ -59,6 +59,10 @@ <td>RFC4253</td> </tr> <tr> + <td>aes12****@opens*****</td> + <td>not RFC5647, PROTOCOL of OpenSSH</td> + </tr> + <tr> <td>camellia128-ctr</td> <td>draft-kanno-secsh-camellia-02</td> </tr> Modified: branches/4-stable/installer/release/TERATERM.INI =================================================================== --- branches/4-stable/installer/release/TERATERM.INI 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/installer/release/TERATERM.INI 2021-05-19 14:11:12 UTC (rev 9254) @@ -823,10 +823,10 @@ ; @...arcfour128, A...arcfour256, B...cast128-cbc, C...3des-ctr, ; D...blowfish-ctr, E...cast128-ctr, F...camellia128-cbc, ; G...camellia192-cbc, H...camellia256-cbc, I...camellia128-ctr, -; J...camellia192-ctr, K...camellia256-ctr L...a****@opens***** -; M...a****@opens***** +; J...camellia192-ctr, K...camellia256-ctr, L...a****@opens***** +; M...a****@opens*****, N...c****@opens***** ; 0...Ciphers below this line are disabled. -CipherOrder=MLK>H:J=G9I<F8C7D;EB30A@?62 +CipherOrder=MKN>H:J=G9LI<F8C7D;EB30A@?62 ; KEX algorithm order(SSH2) ; 1...diffie-hellman-group1-sha1 Index: branches/4-stable/teraterm =================================================================== --- branches/4-stable/teraterm 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/teraterm 2021-05-19 14:11:12 UTC (rev 9254) Property changes on: branches/4-stable/teraterm ___________________________________________________________________ Modified: svn:mergeinfo ## -3,5 +3,6 ## /branches/openssl_1_1_1_v2/teraterm:7819-7822,7829,7832-7834,7838-7843,7846-7847,7855-7856,7858,7861-7863,7979-7980 /branches/openssl_1_1_1_v3/teraterm:8258 /branches/serial_port_improved/teraterm:8119,8140-8141,8144,8150,8158-8160,8163,8170,8172,8183,8185,8204,8209,8212-8215 +/branches/ssh_chacha20poly1305/teraterm:9209-9253 /branches/vs2015_warn/teraterm:6194-6285 /trunk/teraterm:8867 \ No newline at end of property Index: branches/4-stable/ttpmenu =================================================================== --- branches/4-stable/ttpmenu 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttpmenu 2021-05-19 14:11:12 UTC (rev 9254) Property changes on: branches/4-stable/ttpmenu ___________________________________________________________________ Modified: svn:mergeinfo ## -1,2 +1,3 ## +/branches/ssh_chacha20poly1305/ttpmenu:9209-9253 /branches/vs2015_warn/ttpmenu:6194-6285 /trunk/ttpmenu:8867 \ No newline at end of property Modified: branches/4-stable/ttssh2/ttxssh/CMakeLists.txt =================================================================== --- branches/4-stable/ttssh2/ttxssh/CMakeLists.txt 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/CMakeLists.txt 2021-05-19 14:11:12 UTC (rev 9254) @@ -26,8 +26,14 @@ buffer.h chacha.c chacha.h + cipher-3des1.c + cipher-chachapoly-libcrypto.c + cipher-chachapoly.h + cipher-ctr.c + cipher.c cipher.h - cipher-ctr.c + comp.c + comp.h config.h crypt.c crypt.h @@ -47,12 +53,14 @@ ed25519_sc25519.c ed25519_sc25519.h ed25519_verify.c + fwd-socks.c + fwd-socks.h fwd.c fwd.h - fwd-socks.c - fwd-socks.h fwdui.c fwdui.h + hostkey.c + hostkey.h hosts.c hosts.h kex.c @@ -61,19 +69,25 @@ key.h keyfiles.c keyfiles.h + mac.c + mac.h pkt.c pkt.h + poly1305.c + poly1305.h resource.h sftp.c sftp.h ssh.c ssh.h + ssherr.c + ssherr.h + ttxssh-version.h + ttxssh-version.rc ttxssh.c ttxssh.def ttxssh.h ttxssh.rc - ttxssh-version.h - ttxssh-version.rc util.c util.h x11util.c Modified: branches/4-stable/ttssh2/ttxssh/auth.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/auth.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/auth.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/auth.h =================================================================== --- branches/4-stable/ttssh2/ttxssh/auth.h 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/auth.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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; Copied: branches/4-stable/ttssh2/ttxssh/cipher-3des1.c (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-3des1.c) =================================================================== --- branches/4-stable/ttssh2/ttxssh/cipher-3des1.c (rev 0) +++ branches/4-stable/ttssh2/ttxssh/cipher-3des1.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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); +} Copied: branches/4-stable/ttssh2/ttxssh/cipher-chachapoly-libcrypto.c (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-chachapoly-libcrypto.c) =================================================================== --- branches/4-stable/ttssh2/ttxssh/cipher-chachapoly-libcrypto.c (rev 0) +++ branches/4-stable/ttssh2/ttxssh/cipher-chachapoly-libcrypto.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -0,0 +1,199 @@ +/* Imported from OpenSSH-8.5p1, TeraTerm Project */ + +/* + * Copyright (c) 2013 Damien Miller <djm****@mindr*****> + * + * 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. + */ + +/* $OpenBSD: cipher-chachapoly-libcrypto.c,v 1.1 2020/04/03 04:32:21 djm Exp $ */ + +// for Visual Studio 2005 +#pragma warning(disable : 4244) + +#include <sys/types.h> + +#include <stdarg.h> /* needed for log.h */ +#include <string.h> +#include <stdio.h> /* needed for misc.h */ +#include <windows.h> + +#include <openssl/evp.h> + +#include "ssherr.h" +#include "cipher-chachapoly.h" + + +// import from sshbuf.h +/* $OpenBSD: sshbuf.h,v 1.23 2020/06/22 05:54:10 djm Exp $ */ +#define PEEK_U32(p) \ + (((u_int32_t)(((const u_char *)(p))[0]) << 24) | \ + ((u_int32_t)(((const u_char *)(p))[1]) << 16) | \ + ((u_int32_t)(((const u_char *)(p))[2]) << 8) | \ + (u_int32_t)(((const u_char *)(p))[3])) +#define POKE_U64(p, v) \ + do { \ + const u_int64_t __v = (v); \ + ((u_char *)(p))[0] = (__v >> 56) & 0xff; \ + ((u_char *)(p))[1] = (__v >> 48) & 0xff; \ + ((u_char *)(p))[2] = (__v >> 40) & 0xff; \ + ((u_char *)(p))[3] = (__v >> 32) & 0xff; \ + ((u_char *)(p))[4] = (__v >> 24) & 0xff; \ + ((u_char *)(p))[5] = (__v >> 16) & 0xff; \ + ((u_char *)(p))[6] = (__v >> 8) & 0xff; \ + ((u_char *)(p))[7] = __v & 0xff; \ + } while (0) + + +// import from openbsd-compat/timingsafe_bcmp.c +/* $OpenBSD: timingsafe_bcmp.c,v 1.1 2010/09/24 13:33:00 matthew Exp $ */ +int +timingsafe_bcmp(const void* b1, const void* b2, size_t n) +{ + const unsigned char* p1 = b1, * p2 = b2; + int ret = 0; + + for (; n > 0; n--) + ret |= *p1++ ^ *p2++; + return (ret != 0); +} + + +struct chachapoly_ctx { + EVP_CIPHER_CTX *main_evp, *header_evp; +}; + +struct chachapoly_ctx * +chachapoly_new(const u_char *key, u_int keylen) +{ + struct chachapoly_ctx *ctx; + + if (keylen != (32 + 32)) /* 2 x 256 bit keys */ + return NULL; + if ((ctx = calloc(1, sizeof(*ctx))) == NULL) + return NULL; + if ((ctx->main_evp = EVP_CIPHER_CTX_new()) == NULL || + (ctx->header_evp = EVP_CIPHER_CTX_new()) == NULL) + goto fail; + if (!EVP_CipherInit(ctx->main_evp, EVP_chacha20(), key, NULL, 1)) + goto fail; + if (!EVP_CipherInit(ctx->header_evp, EVP_chacha20(), key + 32, NULL, 1)) + goto fail; + if (EVP_CIPHER_CTX_iv_length(ctx->header_evp) != 16) + goto fail; + return ctx; + fail: + chachapoly_free(ctx); + return NULL; +} + +void +chachapoly_free(struct chachapoly_ctx *cpctx) +{ + if (cpctx == NULL) + return; + EVP_CIPHER_CTX_free(cpctx->main_evp); + EVP_CIPHER_CTX_free(cpctx->header_evp); + SecureZeroMemory(cpctx, sizeof(*cpctx)); +} + +/* + * chachapoly_crypt() operates as following: + * En/decrypt with header key 'aadlen' bytes from 'src', storing result + * to 'dest'. The ciphertext here is treated as additional authenticated + * data for MAC calculation. + * En/decrypt 'len' bytes at offset 'aadlen' from 'src' to 'dest'. Use + * POLY1305_TAGLEN bytes at offset 'len'+'aadlen' as the authentication + * tag. This tag is written on encryption and verified on decryption. + */ +int +chachapoly_crypt(struct chachapoly_ctx *ctx, u_int seqnr, u_char *dest, + const u_char *src, u_int len, u_int aadlen, u_int authlen, int do_encrypt) +{ + u_char seqbuf[16]; /* layout: u64 counter || u64 seqno */ + int r = SSH_ERR_INTERNAL_ERROR; + u_char expected_tag[POLY1305_TAGLEN], poly_key[POLY1305_KEYLEN]; + + /* + * Run ChaCha20 once to generate the Poly1305 key. The IV is the + * packet sequence number. + */ + memset(seqbuf, 0, sizeof(seqbuf)); + POKE_U64(seqbuf + 8, seqnr); + memset(poly_key, 0, sizeof(poly_key)); + if (!EVP_CipherInit(ctx->main_evp, NULL, NULL, seqbuf, 1) || + EVP_Cipher(ctx->main_evp, poly_key, + poly_key, sizeof(poly_key)) < 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + + /* If decrypting, check tag before anything else */ + if (!do_encrypt) { + const u_char *tag = src + aadlen + len; + + poly1305_auth(expected_tag, src, aadlen + len, poly_key); + if (timingsafe_bcmp(expected_tag, tag, POLY1305_TAGLEN) != 0) { + r = SSH_ERR_MAC_INVALID; + goto out; + } + } + + /* Crypt additional data */ + if (aadlen) { + if (!EVP_CipherInit(ctx->header_evp, NULL, NULL, seqbuf, 1) || + EVP_Cipher(ctx->header_evp, dest, src, aadlen) < 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + } + + /* Set Chacha's block counter to 1 */ + seqbuf[0] = 1; + if (!EVP_CipherInit(ctx->main_evp, NULL, NULL, seqbuf, 1) || + EVP_Cipher(ctx->main_evp, dest + aadlen, src + aadlen, len) < 0) { + r = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + + /* If encrypting, calculate and append tag */ + if (do_encrypt) { + poly1305_auth(dest + aadlen + len, dest, aadlen + len, + poly_key); + } + r = 0; + out: + SecureZeroMemory(expected_tag, sizeof(expected_tag)); + SecureZeroMemory(seqbuf, sizeof(seqbuf)); + SecureZeroMemory(poly_key, sizeof(poly_key)); + return r; +} + +/* Decrypt and extract the encrypted packet length */ +int +chachapoly_get_length(struct chachapoly_ctx *ctx, + u_int *plenp, u_int seqnr, const u_char *cp, u_int len) +{ + u_char buf[4], seqbuf[16]; + + if (len < 4) + return SSH_ERR_MESSAGE_INCOMPLETE; + memset(seqbuf, 0, sizeof(seqbuf)); + POKE_U64(seqbuf + 8, seqnr); + if (!EVP_CipherInit(ctx->header_evp, NULL, NULL, seqbuf, 0)) + return SSH_ERR_LIBCRYPTO_ERROR; + if (EVP_Cipher(ctx->header_evp, buf, (u_char *)cp, sizeof(buf)) < 0) + return SSH_ERR_LIBCRYPTO_ERROR; + *plenp = PEEK_U32(buf); + return 0; +} Copied: branches/4-stable/ttssh2/ttxssh/cipher-chachapoly.h (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher-chachapoly.h) =================================================================== --- branches/4-stable/ttssh2/ttxssh/cipher-chachapoly.h (rev 0) +++ branches/4-stable/ttssh2/ttxssh/cipher-chachapoly.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -0,0 +1,44 @@ +/* Imported from OpenSSH-8.5p1, TeraTerm Project */ + +/* $OpenBSD: cipher-chachapoly.h,v 1.5 2020/04/03 04:27:03 djm Exp $ */ + +/* + * Copyright (c) Damien Miller 2013 <djm****@mindr*****> + * + * 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 CHACHA_POLY_AEAD_H +#define CHACHA_POLY_AEAD_H + +#include <sys/types.h> +typedef unsigned int u_int32_t; +typedef unsigned long long u_int64_t; + +#include "chacha.h" +#include "poly1305.h" + +#define CHACHA_KEYLEN 32 /* Only 256 bit keys used here */ + +struct chachapoly_ctx; +typedef struct chachapoly_ctx chachapoly_ctx; + +struct chachapoly_ctx* chachapoly_new(const u_char* key, u_int keylen); +void chachapoly_free(struct chachapoly_ctx* cpctx); + +int chachapoly_crypt(struct chachapoly_ctx* cpctx, u_int seqnr, + u_char* dest, const u_char* src, u_int len, u_int aadlen, u_int authlen, + int do_encrypt); +int chachapoly_get_length(struct chachapoly_ctx* cpctx, + u_int* plenp, u_int seqnr, const u_char* cp, u_int len); + +#endif /* CHACHA_POLY_AEAD_H */ Copied: branches/4-stable/ttssh2/ttxssh/cipher.c (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c) =================================================================== --- branches/4-stable/ttssh2/ttxssh/cipher.c (rev 0) +++ branches/4-stable/ttssh2/ttxssh/cipher.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -0,0 +1,634 @@ +/* + * 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 + {SSH2_CIPHER_CHACHAPOLY, "chach****@opens*****", 8, 64, 0, 0, 16, EVP_enc_null}, + {SSH_CIPHER_NONE, "none", 8, 0, 0, 0, 0, EVP_enc_null}, // for no passphrase key file + {SSH_CIPHER_3DES, "3des", 8, 16, 0, 0, 0, evp_ssh1_3des}, // for RSA1 key file +}; + + +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 || cipher->id == SSH2_CIPHER_CHACHAPOLY) { + 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*****"; + case SSH2_CIPHER_CHACHAPOLY: + return "chach****@opens*****(SSH2)"; + + 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)"; + case SSH2_CIPHER_CHACHAPOLY: + return "chach****@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_CHACHAPOLY, + 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; + case SSH2_CIPHER_CHACHAPOLY: + c_str = "chach****@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 +// +int cipher_init_SSH2( + struct sshcipher_ctx **ccp, const struct ssh2cipher *cipher, + const u_char *key, u_int keylen, + const u_char *iv, u_int ivlen, + int do_encrypt, + PTInstVar pvar) +{ + struct sshcipher_ctx *cc = NULL; + int ret = SSH_ERR_INTERNAL_ERROR; + const EVP_CIPHER *type; + int klen; + unsigned char *junk = NULL, *discard = NULL; + char tmp[80]; + + *ccp = NULL; + if ((cc = calloc(sizeof(*cc), 1)) == NULL) { + 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 SSH_ERR_ALLOC_FAIL; + } + + if (keylen < cipher->key_len) { + 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); + ret = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + if (iv != NULL && ivlen < get_cipher_iv_len(cipher)) { + 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); + ret = SSH_ERR_INVALID_ARGUMENT; + goto out; + } + + cc->cipher = cipher; + if (cipher->id == SSH2_CIPHER_CHACHAPOLY) { + cc->cp_ctx = chachapoly_new(key, keylen); + ret = cc->cp_ctx != NULL ? 0 : SSH_ERR_INVALID_ARGUMENT; + if (ret == SSH_ERR_INVALID_ARGUMENT) { + 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); + } + goto out; + } + type = (*cipher->func)(); + if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) { + 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); + ret = SSH_ERR_ALLOC_FAIL; + goto out; + } + if (EVP_CipherInit(cc->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, 6); + notify_fatal_error(pvar, tmp, TRUE); + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + if (get_cipher_auth_len(cipher) && + !EVP_CIPHER_CTX_ctrl(cc->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, 7); + notify_fatal_error(pvar, tmp, TRUE); + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + klen = EVP_CIPHER_CTX_key_length(cc->evp); + if (klen > 0 && keylen != (u_int)klen) { + if (EVP_CIPHER_CTX_set_key_length(cc->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, 8); + notify_fatal_error(pvar, tmp, TRUE); + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + } + if (EVP_CipherInit(cc->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, 9); + notify_fatal_error(pvar, tmp, TRUE); + ret = SSH_ERR_LIBCRYPTO_ERROR; + goto out; + } + + if (cipher->discard_len > 0) { + junk = malloc(cipher->discard_len); + discard = malloc(cipher->discard_len); + if (junk == NULL || discard == NULL || + EVP_Cipher(cc->evp, discard, junk, cipher->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, 10); + notify_fatal_error(pvar, tmp, TRUE); + } + else { + SecureZeroMemory(discard, cipher->discard_len); + } + free(junk); + free(discard); + } + ret = 0; + +out: + if (ret == 0) { + *ccp = cc; + } + else { + if (cc != NULL) { + EVP_CIPHER_CTX_free(cc->evp); + SecureZeroMemory(cc, sizeof(*cc)); + } + } + return ret; +} + +// +// SSH2\x97p\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82̔j\x8A\xFC +/// +void cipher_free_SSH2(struct sshcipher_ctx *cc) +{ + if (cc == NULL) + return; + if (cc->cipher->id == SSH2_CIPHER_CHACHAPOLY) { + chachapoly_free(cc->cp_ctx); + cc->cp_ctx = NULL; + } + EVP_CIPHER_CTX_free(cc->evp); + cc->evp = NULL; + SecureZeroMemory(cc, sizeof(*cc)); +} Modified: branches/4-stable/ttssh2/ttxssh/cipher.h =================================================================== --- branches/4-stable/ttssh2/ttxssh/cipher.h 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/cipher.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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,7 +39,12 @@ #ifndef CIPHER_H #define CIPHER_H +typedef unsigned int u_int; +typedef unsigned char u_char; + #include <openssl/evp.h> +#include "cipher-chachapoly.h" + /* * Cipher types for SSH-1. New types can be added, but old types should not * be removed for compatibility. The maximum allowed value is 31. @@ -45,60 +52,89 @@ #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 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 +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); + +int cipher_init_SSH2( + struct sshcipher_ctx **ccp, const struct ssh2cipher *cipher, + const u_char *key, u_int keylen, + const u_char *iv, u_int ivlen, + int do_encrypt, + PTInstVar pvar ); +void cipher_free_SSH2(struct sshcipher_ctx *cc); -void cipher_cleanup_SSH2(EVP_CIPHER_CTX *evp); - #endif /* CIPHER_H */ Copied: branches/4-stable/ttssh2/ttxssh/comp.c (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.c) =================================================================== --- branches/4-stable/ttssh2/ttxssh/comp.c (rev 0) +++ branches/4-stable/ttssh2/ttxssh/comp.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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 + } +} Copied: branches/4-stable/ttssh2/ttxssh/comp.h (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/comp.h) =================================================================== --- branches/4-stable/ttssh2/ttxssh/comp.h (rev 0) +++ branches/4-stable/ttssh2/ttxssh/comp.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/crypt.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/crypt.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/crypt.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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; @@ -206,7 +204,8 @@ unsigned int block_size = pvar->ssh2_keys[MODE_OUT].enc.block_size; unsigned char lastiv[1]; char tmp[80]; - EVP_CIPHER_CTX *evp = pvar->evpcip[MODE_OUT]; + struct sshcipher_ctx *cc = pvar->cc[MODE_OUT]; + unsigned int newbuff_len = bytes; if (bytes == 0) return TRUE; @@ -220,28 +219,44 @@ return FALSE; } - if (bytes > encbufflen) { - if ((newbuff = realloc(encbuff, bytes)) == NULL) + if (cc->cipher->id == SSH2_CIPHER_CHACHAPOLY) { + // chacha20-poly1305 \x82ł\xCD aadlen \x82\xE0\x88Í\x86\x89\xBB\x82̑Ώ\xDB + // aadlen \x82\xC6 bytes \x82͕ʁX\x82ɈÍ\x86\x89\xBB\x82\xB3\x82\xEA\x82\xE9 + // chachapoly_crypt \x82̒\x86\x82ŔF\x8Ff\x81[\x83^(AEAD tag)\x82\xE0\x90\xB6\x90\xAC\x82\xB3\x82\xEA\x82\xE9 + newbuff_len += aadlen + authlen; + } + if (newbuff_len > encbufflen) { + if ((newbuff = realloc(encbuff, newbuff_len)) == NULL) goto err; encbuff = newbuff; - encbufflen = bytes; + encbufflen = newbuff_len; } - if (!EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) + if (cc->cipher->id == SSH2_CIPHER_CHACHAPOLY) { + if (chachapoly_crypt(cc->cp_ctx, pvar->ssh_state.sender_sequence_number, + encbuff, data, bytes, aadlen, authlen, 1) != 0) { + goto err; + } + memcpy(data, encbuff, aadlen + bytes + authlen); + return TRUE; + } + + if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) goto err; - if (aadlen && !EVP_Cipher(evp, NULL, data, aadlen) < 0) + if (aadlen && !EVP_Cipher(cc->evp, NULL, data, aadlen) < 0) goto err; - if (EVP_Cipher(evp, encbuff, data+aadlen, bytes) < 0) + // AES-GCM \x82ł\xCD aadlen \x82\xF0\x88Í\x86\x89\xBB\x82\xB5\x82Ȃ\xA2\x82̂ŁA\x82\xBB\x82̐悾\x82\xAF\x88Í\x86\x89\xBB\x82\xB7\x82\xE9 + if (EVP_Cipher(cc->evp, encbuff, data+aadlen, bytes) < 0) goto err; memcpy(data+aadlen, encbuff, bytes); - if (EVP_Cipher(evp, NULL, NULL, 0) < 0) + if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0) goto err; - if (!EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_GET_TAG, authlen, data+aadlen+bytes)) + if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, authlen, data+aadlen+bytes)) goto err; return TRUE; @@ -260,7 +275,8 @@ unsigned int block_size = pvar->ssh2_keys[MODE_IN].enc.block_size; unsigned char lastiv[1]; char tmp[80]; - EVP_CIPHER_CTX *evp = pvar->evpcip[MODE_IN]; + struct sshcipher_ctx *cc = pvar->cc[MODE_IN]; + unsigned int newbuff_len = bytes; if (bytes == 0) return TRUE; @@ -274,32 +290,46 @@ return FALSE; } - if (bytes > encbufflen) { - if ((newbuff = realloc(encbuff, bytes)) == NULL) + if (cc->cipher->id == SSH2_CIPHER_CHACHAPOLY) { + // chacha20-poly1305 \x82ł\xCD aadlen \x82\xE0\x88Í\x86\x89\xBB\x82\xB3\x82\xEA\x82Ă\xA2\x82\xE9 + newbuff_len += aadlen; + } + if (newbuff_len > encbufflen) { + if ((newbuff = realloc(encbuff, newbuff_len)) == NULL) goto err; encbuff = newbuff; - encbufflen = bytes; + encbufflen = newbuff_len; } - if (!EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) + if (cc->cipher->id == SSH2_CIPHER_CHACHAPOLY) { + if (chachapoly_crypt(cc->cp_ctx, pvar->ssh_state.receiver_sequence_number, + encbuff, data, bytes, aadlen, authlen, 0) != 0) { + goto err; + } + memcpy(data, encbuff, aadlen + bytes); + return TRUE; + } + + if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, 1, lastiv)) goto err; - if (!EVP_CIPHER_CTX_ctrl(evp, EVP_CTRL_GCM_SET_TAG, authlen, data+aadlen+bytes)) + if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, authlen, data+aadlen+bytes)) goto err; - if (aadlen && !EVP_Cipher(evp, NULL, data, aadlen) < 0) + if (aadlen && !EVP_Cipher(cc->evp, NULL, data, aadlen) < 0) goto err; - if (EVP_Cipher(evp, encbuff, data+aadlen, bytes) < 0) + // AES-GCM \x82ł\xCD aadlen \x82\xF0\x88Í\x86\x89\xBB\x82\xB5\x82Ȃ\xA2\x82̂ŁA\x82\xBB\x82̐悾\x82\xAF\x95\x9C\x8D\x86\x82\xB7\x82\xE9 + if (EVP_Cipher(cc->evp, encbuff, data+aadlen, bytes) < 0) goto err; memcpy(data+aadlen, encbuff, bytes); - if (EVP_Cipher(evp, NULL, NULL, 0) < 0) - return FALSE; - else - return TRUE; + if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0) + 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, @@ -338,7 +368,7 @@ encbufflen = bytes; } - if (EVP_Cipher(pvar->evpcip[MODE_OUT], encbuff, buf, bytes) == 0) { + if (EVP_Cipher(pvar->cc[MODE_OUT]->evp, encbuff, buf, bytes) == 0) { UTIL_get_lang_msg("MSG_ENCRYPT_ERROR2", pvar, "%s encrypt error(2)"); _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, get_cipher_name(pvar->crypt_state.sender_cipher)); @@ -374,7 +404,7 @@ encbufflen = bytes; } - if (EVP_Cipher(pvar->evpcip[MODE_IN], encbuff, buf, bytes) == 0) { + if (EVP_Cipher(pvar->cc[MODE_IN]->evp, encbuff, buf, bytes) == 0) { UTIL_get_lang_msg("MSG_DECRYPT_ERROR2", pvar, "%s decrypt error(2)"); _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, get_cipher_name(pvar->crypt_state.receiver_cipher)); @@ -489,8 +519,8 @@ // make_key()\x82\xF0 fingerprint \x90\xB6\x90\xAC\x82ł\xE0\x97\x98\x97p\x82\xB7\x82\xE9\x82̂ŁAstatic\x82\xF0\x8D폜\x81B(2006.3.27 yutaka) RSA *make_key(PTInstVar pvar, - int bits, unsigned char *exp, - unsigned char *mod) + int bits, unsigned char *exp, + unsigned char *mod) { RSA *key = RSA_new(); BIGNUM *e = NULL, *n = NULL; @@ -595,6 +625,7 @@ | (1 << SSH2_CIPHER_CAMELLIA256_CTR) | (1 << SSH2_CIPHER_AES128_GCM) | (1 << SSH2_CIPHER_AES256_GCM) + | (1 << SSH2_CIPHER_CHACHAPOLY) ); } @@ -665,7 +696,7 @@ // \x81\xA6\x96{\x8A\x94\x82\xCD SSH2 \x82ł̂ݎg\x97p\x82\xB3\x82\xEA\x82\xE9\x81B // (2004.12.17 yutaka) BOOL CRYPT_verify_receiver_MAC(PTInstVar pvar, uint32 sequence_number, - char *data, int len, char *MAC) + char *data, int len, char *MAC) { HMAC_CTX *c = NULL; unsigned char m[EVP_MAX_MD_SIZE]; @@ -685,7 +716,7 @@ if ((u_int)mac->mac_len > sizeof(m)) { logprintf(LOG_LEVEL_VERBOSE, "HMAC len(%d) is larger than %d bytes(seq %lu len %d)", - mac->mac_len, sizeof(m), sequence_number, len); + mac->mac_len, sizeof(m), sequence_number, len); goto error; } @@ -802,13 +833,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]); } } @@ -1003,7 +1034,7 @@ SSH_RSA_CHALLENGE_LENGTH, SSH_RSA_CHALLENGE_LENGTH); } else { SecureZeroMemory(decrypted_challenge, - SSH_RSA_CHALLENGE_LENGTH - decrypted_challenge_len); + SSH_RSA_CHALLENGE_LENGTH - decrypted_challenge_len); memcpy(decrypted_challenge + SSH_RSA_CHALLENGE_LENGTH - decrypted_challenge_len, challenge, decrypted_challenge_len); @@ -1046,98 +1077,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_init(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_cleanup_SSH2(EVP_CIPHER_CTX *evp) -{ - EVP_CIPHER_CTX_cleanup(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) { @@ -1171,15 +1116,11 @@ cipher = pvar->ciphers[MODE_OUT]; if (cipher) { enc = &pvar->ssh2_keys[MODE_OUT].enc; - cipher_init_SSH2(pvar->evpcip[MODE_OUT], - enc->key, get_cipher_key_len(cipher), - enc->iv, get_cipher_iv_len(cipher), + cipher_init_SSH2(&pvar->cc[MODE_OUT], cipher, + enc->key, enc->key_len, + enc->iv, enc->iv_len, CIPHER_ENCRYPT, - get_cipher_EVP_CIPHER(cipher), - get_cipher_discard_len(cipher), - get_cipher_auth_len(cipher), pvar); - pvar->crypt_state.encrypt = crypt_SSH2_encrypt; } else { @@ -1219,15 +1160,11 @@ cipher = pvar->ciphers[MODE_IN]; if (cipher) { enc = &pvar->ssh2_keys[MODE_IN].enc; - cipher_init_SSH2(pvar->evpcip[MODE_IN], - enc->key, get_cipher_key_len(cipher), - enc->iv, get_cipher_iv_len(cipher), + cipher_init_SSH2(&pvar->cc[MODE_IN], cipher, + enc->key, enc->key_len, + enc->iv, enc->iv_len, CIPHER_DECRYPT, - get_cipher_EVP_CIPHER(cipher), - get_cipher_discard_len(cipher), - get_cipher_auth_len(cipher), pvar); - pvar->crypt_state.decrypt = crypt_SSH2_decrypt; } else { @@ -1262,71 +1199,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, @@ -1392,18 +1264,18 @@ if (pvar->crypt_state.detect_attack_statics.h != NULL) { SecureZeroMemory(pvar->crypt_state.detect_attack_statics.h, - pvar->crypt_state.detect_attack_statics.n * HASH_ENTRYSIZE); + pvar->crypt_state.detect_attack_statics.n * HASH_ENTRYSIZE); free(pvar->crypt_state.detect_attack_statics.h); } SecureZeroMemory(pvar->crypt_state.sender_cipher_key, - sizeof(pvar->crypt_state.sender_cipher_key)); + sizeof(pvar->crypt_state.sender_cipher_key)); SecureZeroMemory(pvar->crypt_state.receiver_cipher_key, - sizeof(pvar->crypt_state.receiver_cipher_key)); + sizeof(pvar->crypt_state.receiver_cipher_key)); SecureZeroMemory(pvar->crypt_state.server_cookie, - sizeof(pvar->crypt_state.server_cookie)); + sizeof(pvar->crypt_state.server_cookie)); SecureZeroMemory(pvar->crypt_state.client_cookie, - sizeof(pvar->crypt_state.client_cookie)); + sizeof(pvar->crypt_state.client_cookie)); SecureZeroMemory(&pvar->crypt_state.enc, sizeof(pvar->crypt_state.enc)); SecureZeroMemory(&pvar->crypt_state.dec, sizeof(pvar->crypt_state.dec)); } @@ -1453,7 +1325,7 @@ SecureZeroMemory(state.ivec, 8); flip_endianness(buf, bytes); BF_cbc_encrypt(buf, buf, bytes, &state.k, state.ivec, - BF_DECRYPT); + BF_DECRYPT); flip_endianness(buf, bytes); break; } Copied: branches/4-stable/ttssh2/ttxssh/hostkey.c (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.c) =================================================================== --- branches/4-stable/ttssh2/ttxssh/hostkey.c (rev 0) +++ branches/4-stable/ttssh2/ttxssh/hostkey.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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; +} Copied: branches/4-stable/ttssh2/ttxssh/hostkey.h (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/hostkey.h) =================================================================== --- branches/4-stable/ttssh2/ttxssh/hostkey.h (rev 0) +++ branches/4-stable/ttssh2/ttxssh/hostkey.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/hosts.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/hosts.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/hosts.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/kex.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/kex.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/kex.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/kex.h =================================================================== --- branches/4-stable/ttssh2/ttxssh/kex.h 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/kex.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/key.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/key.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/key.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/key.h =================================================================== --- branches/4-stable/ttssh2/ttxssh/key.h 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/key.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/keyfiles.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/keyfiles.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/keyfiles.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -354,12 +354,12 @@ // bcrypt KDF \x8C`\x8E\xAE\x82œǂ\xDE // based on key_parse_private2() @ OpenSSH 6.5 static Key *read_SSH2_private2_key(PTInstVar pvar, - FILE * fp, - char * passphrase, - BOOL * invalid_passphrase, - BOOL is_auto_login, - char *errmsg, - int errmsg_len) + FILE * fp, + char * passphrase, + BOOL * invalid_passphrase, + BOOL is_auto_login, + char *errmsg, + int errmsg_len) { /* (A) * buffer_consume\x8Cn\x8A\x94\x82\xF0\x8Eg\x82\xA4\x8Fꍇ\x82́Abuffer_len\x82\xC6buffer_ptr\x82\xAA\x8Eg\x82\xA6\x82Ȃ\xA2\x82̂ŁA @@ -379,9 +379,9 @@ 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; + struct sshcipher_ctx *cc = NULL; int ret; blob = buffer_init(); @@ -389,9 +389,8 @@ kdf = buffer_init(); encoded = buffer_init(); copy_consumed = buffer_init(); - cipher_ctx = EVP_CIPHER_CTX_new(); - if (blob == NULL || b == NULL || kdf == NULL || encoded == NULL || copy_consumed == NULL || cipher_ctx == NULL) + if (blob == NULL || b == NULL || kdf == NULL || encoded == NULL || copy_consumed == NULL) goto error; // \x83t\x83@\x83C\x83\x8B\x82\xF0\x82\xB7\x82ׂēǂݍ\x9E\x82\xDE @@ -552,14 +551,11 @@ // \x95\x9C\x8D\x86\x89\xBB cp = buffer_append_space(b, len); - cipher_init_SSH2(cipher_ctx, key, keylen, key + keylen, ivlen, CIPHER_DECRYPT, - get_cipher_EVP_CIPHER(cipher), 0, 0, pvar); - ret = EVP_Cipher(cipher_ctx, cp, buffer_tail_ptr(copy_consumed), len); + cipher_init_SSH2(&cc, cipher, key, keylen, key + keylen, ivlen, CIPHER_DECRYPT, pvar); + ret = EVP_Cipher(cc->evp, cp, buffer_tail_ptr(copy_consumed), len); if (ret == 0) { - cipher_cleanup_SSH2(cipher_ctx); goto error; } - cipher_cleanup_SSH2(cipher_ctx); buffer_consume(copy_consumed, len); if (buffer_remain_len(copy_consumed) != 0) { @@ -607,6 +603,7 @@ buffer_free(kdf); buffer_free(encoded); buffer_free(copy_consumed); + cipher_free_SSH2(cc); free(ciphername); free(kdfname); @@ -615,10 +612,6 @@ free(salt); free(comment); - if (cipher_ctx) { - EVP_CIPHER_CTX_free(cipher_ctx); - } - // KDF \x82ł͂Ȃ\xA9\x82\xC1\x82\xBD if (keyfmt == NULL) { fseek(fp, 0, SEEK_SET); @@ -817,6 +810,8 @@ int i, len, len2; char *encname = NULL, *comment = NULL, *private_mac = NULL; buffer_t *pubkey = NULL, *prikey = NULL; + const struct ssh2cipher *cipher = NULL; + struct sshcipher_ctx *cc = NULL; result = (Key *)malloc(sizeof(Key)); ZeroMemory(result, sizeof(Key)); @@ -943,7 +938,7 @@ } cipher_ctx = EVP_CIPHER_CTX_new(); - if (ctx == NULL) { + if (cipher_ctx == NULL) { EVP_MD_CTX_free(ctx); goto error; } @@ -963,22 +958,21 @@ memset(iv, 0, sizeof(iv)); // decrypt - cipher_init_SSH2(cipher_ctx, key, 32, iv, 16, CIPHER_DECRYPT, EVP_aes_256_cbc(), 0, 0, pvar); + cipher = get_cipher_by_name("aes256-cbc"); + cipher_init_SSH2(&cc, cipher, key, 32, iv, 16, CIPHER_DECRYPT, pvar); len = buffer_len(prikey); decrypted = (char *)malloc(len); - ret = EVP_Cipher(cipher_ctx, decrypted, prikey->buf, len); + ret = EVP_Cipher(cc->evp, decrypted, prikey->buf, len); if (ret == 0) { strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); free(decrypted); - cipher_cleanup_SSH2(cipher_ctx); - EVP_CIPHER_CTX_free(cipher_ctx); + cipher_free_SSH2(cc); goto error; } buffer_clear(prikey); buffer_append(prikey, decrypted, len); free(decrypted); - cipher_cleanup_SSH2(cipher_ctx); - EVP_CIPHER_CTX_free(cipher_ctx); + cipher_free_SSH2(cc); } // verity MAC @@ -989,9 +983,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); @@ -1395,6 +1389,8 @@ int encflag; char *encname = NULL; buffer_t *blob = NULL, *blob2 = NULL; + const struct ssh2cipher *cipher = NULL; + struct sshcipher_ctx *cc = NULL; result = (Key *)malloc(sizeof(Key)); ZeroMemory(result, sizeof(Key)); @@ -1536,19 +1532,18 @@ memset(iv, 0, sizeof(iv)); // decrypt - cipher_init_SSH2(cipher_ctx, key, 24, iv, 8, CIPHER_DECRYPT, EVP_des_ede3_cbc(), 0, 0, pvar); + cipher = get_cipher_by_name("3des-cbc"); + cipher_init_SSH2(&cc, cipher, key, 24, iv, 8, CIPHER_DECRYPT, pvar); decrypted = (char *)malloc(len); - ret = EVP_Cipher(cipher_ctx, decrypted, blob->buf + blob->offset, len); + ret = EVP_Cipher(cc->evp, decrypted, blob->buf + blob->offset, len); if (ret == 0) { strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); - cipher_cleanup_SSH2(cipher_ctx); - EVP_CIPHER_CTX_free(cipher_ctx); + cipher_free_SSH2(cc); goto error; } buffer_append(blob2, decrypted, len); free(decrypted); - cipher_cleanup_SSH2(cipher_ctx); - EVP_CIPHER_CTX_free(cipher_ctx); + cipher_free_SSH2(cc); *invalid_passphrase = TRUE; } Copied: branches/4-stable/ttssh2/ttxssh/mac.c (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.c) =================================================================== --- branches/4-stable/ttssh2/ttxssh/mac.c (rev 0) +++ branches/4-stable/ttssh2/ttxssh/mac.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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; +} Copied: branches/4-stable/ttssh2/ttxssh/mac.h (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/mac.h) =================================================================== --- branches/4-stable/ttssh2/ttxssh/mac.h (rev 0) +++ branches/4-stable/ttssh2/ttxssh/mac.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/pkt.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/pkt.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/pkt.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -176,64 +176,115 @@ } else if (pvar->pkt_state.seen_server_ID && pvar->pkt_state.datalen >= SSH_get_min_packet_size(pvar)) { char *data = pvar->pkt_state.buf + pvar->pkt_state.datastart; - uint32 padding; - uint32 pktsize; + uint32 padding_size = 0; + uint32 pktsize = 0; uint32 total_packet_size; struct Mac *mac = &pvar->ssh2_keys[MODE_IN].mac; struct Enc *enc = &pvar->ssh2_keys[MODE_IN].enc; - int aadlen; + int authlen = 0, aadlen = 0; - /* - * aadlen: Additional Authenticated Data Length - * - \x88Í\x86\x89\xBB\x82\xB5\x82Ȃ\xA2\x82\xAA MAC \x82\xE2 AEAD \x82ł̔F\x8F̑ΏۂƂȂ\xE9\x83f\x81[\x83^\x82̒\xB7\x82\xB3 - * - * EtM \x95\xFB\x8E\xAE\x82\xCC MAC \x82\xE2\x81AAEAD \x82ȈÍ\x86\x82ł̓p\x83P\x83b\x83g\x82̐擪\x82̃p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82͈Í\x86\x89\xBB\x82\xB3\x82ꂸ - * \x94F\x8F݂̂\xAA\x8Ds\x82\xED\x82\xEA\x82\xE9\x81B\x83p\x83P\x83b\x83g\x92\xB7\x82\xCD uint32 (4\x83o\x83C\x83g) \x82Ŋi\x94[\x82\xB3\x82\xEA\x82Ă\xA2\x82\xE9\x81B - * \x92ʏ\xED\x82\xCC MAC \x95\xFB\x8E\xAE (E&M) \x82ŁA\x82\xA9\x82\xC2 AEAD \x82łȂ\xA2\x88Í\x86\x95\xFB\x8E\xAE\x82ł̓p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82\xE0\x88Í\x86\x89\xBB - * \x82\xB3\x82\xEA\x82\xE9\x82̂\xC5 aadlen \x82\xCD 0 \x82ƂȂ\xE9\x81B - */ - if (SSHv2(pvar) && ((mac && mac->etm) || (enc && enc->auth_len > 0))) { - aadlen = 4; + if (SSHv2(pvar)) { + /* + * pktsize + * uint32 packet_length + * \x82\xCD + * byte padding_length + * byte[n1] payload; n1 = packet_length - padding_length - 1 + * byte[n2] random padding; n2 = padding_length + * \x82̒\xB7\x82\xB3\x82̍\x87\x8Cv\x82\xC5 + * byte[m] mac (Message Authentication Code - MAC); m = mac_length + * \x82̒\xB7\x82\xB3\x82\xF0\x8A܂܂Ȃ\xA2\x81B + * cf. RFC 4253 6. Binary Packet Protocol + */ + + if (enc && enc->auth_len > 0) { + authlen = enc->auth_len; + } + + /* + * | | lead 4 bytes are encrypted | aadlen | + * Encryption type + * enc->auth_len > 0 | AEAD | AES-GCM ... no | 4 | (2) + * | | chacha20-poly1305 ... yes | 4 | (1) (2) + * enc->auth_len == 0 | not AEAD | depends on MAC type | <- | + * MAC type + * mac->etm == true | EtM | no | 4 | + * mac->etm == false | E&M | yes | 0 | + * (1) lead 4 bytes are encrypted separately from main part. + * (2) implicit MAC type of AEAD is EtM + */ + /* + * aadlen: Additional Authenticated Data Length + * MAC \x82̑ΏۂƂȂ\xE9\x83f\x81[\x83^\x82ƈꏏ\x82ɈÍ\x86\x89\xBB\x82\xB3\x82\xEA\x82Ȃ\xA2\x81A"MAC \x82̑ΏۂƂȂ\xE9\x83f\x81[\x83^\x82̒\xB7\x82\xB3"\x82̃T\x83C\x83Y + * \x82\xB1\x82̕\x94\x95\xAA\x82\xCD packet_length \x82ŁAuint32 (4\x83o\x83C\x83g) + * + * - \x92ʏ\xED\x82\xCC MAC \x95\xFB\x8E\xAE (E&M) \x82ł̓p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82\xAA\x88ꏏ\x82ɈÍ\x86\x89\xBB\x82\xB3\x82\xEA\x82\xE9\x82̂\xC5 aadlen \x82\xCD 0 \x82ƂȂ\xE9\x81B + * - EtM \x95\xFB\x8E\xAE\x82\xCC MAC \x82\xE2 AEAD \x82\xCC AES-GCM \x82ł́A\x83p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82\xAA\x88Í\x86\x89\xBB\x82\xB3\x82\xEA\x82Ȃ\xA2\x82̂\xC5 + * aadlen \x82\xCD 4 \x82ƂȂ\xE9\x81B + * - AEAD \x82\xCC chacha20-poly1305 \x82ł̓p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82\xAA\x88Í\x86\x89\xBB\x82\xB3\x82\xEA\x82邪\x81AMAC \x82̑ΏۂƂȂ\xE9\x83f\x81[\x83^ + * \x82Ƃ͕ʂɈÍ\x86\x89\xBB\x82\xB3\x82\xEA\x82\xE9\x82̂\xC5 aadlen \x82\xCD 4 \x82ƂȂ\xE9\x81B + * + */ + if ((mac && mac->etm) || authlen > 0) { + aadlen = 4; + } + + if (authlen > 0 && + pvar->cc[MODE_IN]->cipher->id == SSH2_CIPHER_CHACHAPOLY) { + /* + * AEAD \x82\xCC chacha20-poly1305 \x82ł̓p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82\xAA\x95ʂɈÍ\x86\x89\xBB\x82\xB3\x82\xEA\x82Ă\xA2\x82\xE9\x81B + * \x82\xB1\x82̏\x88\x97\x9D\x82͒\xB7\x82\xB3\x82\xF0\x8E擾\x82\xB7\x82邪\x81Adata \x82͈Í\x86\x89\xBB\x82\xB3\x82ꂽ\x82܂܂ƂȂ\xE9\x81B + */ + chachapoly_get_length(pvar->cc[MODE_IN]->cp_ctx, &pktsize, + pvar->ssh_state.receiver_sequence_number, + data, pvar->pkt_state.datalen); + } + else if (authlen == 0 && + aadlen == 0 && + !pvar->pkt_state.predecrypted_packet && aadlen == 0) { + /* + * AEAD \x82łȂ\xAD E&M (aadlen \x82\xAA 0) \x82̎\x9E\x82́A\x88Í\x86\x89\xBB\x82\xB3\x82\xEA\x82Ă\xA2\x82\xE9\x83p\x83P\x83b\x83g\x92\xB7\x82\xF0 + * \x92m\x82\xE9\x95K\x97v\x82\xAA\x97L\x82邽\x82߁A\x90擪\x82\xCC 1 \x83u\x83\x8D\x83b\x83N\x82\xBE\x82\xAF\x8E\x96\x91O\x82ɕ\x9C\x8D\x86\x82\xB7\x82\xE9\x81B + */ + SSH_predecrypt_packet(pvar, data); + pvar->pkt_state.predecrypted_packet = TRUE; + + pktsize = get_uint32_MSBfirst(data); + } + else { + /* + * EtM \x95\xFB\x8E\xAE\x82\xCC MAC \x82\xE2\x81AAEAD \x82\xC5 AES-GCM \x82̂Ƃ\xAB\x82Ȃǂ͂\xBB\x82̂܂ܓǂ߂\xE9\x81B + */ + pktsize = get_uint32_MSBfirst(data); + } } else { - aadlen = 0; + pktsize = get_uint32_MSBfirst(data); } - /* - * aadlen \x82\xAA 0 \x82̎\x9E\x82̓p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82\xAA\x88Í\x86\x89\xBB\x82\xB3\x82\xEA\x82Ă\xA2\x82\xE9\x81B\x83p\x83P\x83b\x83g\x91S\x91̂\xF0\x8E\xF3\x90M\x82\xB5\x82Ă\xA9\x82\xE7 - * \x8C\xE3\x92i\x82̏\x88\x97\x9D\x82\xF0\x8Ds\x82\xA4\x88ׂɃp\x83P\x83b\x83g\x92\xB7\x82\xF0\x92m\x82\xE9\x95K\x97v\x82\xAA\x97L\x82\xE9\x88ׁA\x90擪\x82\xCC 1 \x83u\x83\x8D\x83b\x83N\x82\x86\x82\xB7\x82\xE9\x81B - */ - if (SSHv2(pvar) && !pvar->pkt_state.predecrypted_packet && aadlen == 0) { - SSH_predecrypt_packet(pvar, data); - pvar->pkt_state.predecrypted_packet = TRUE; - } - - // \x83p\x83P\x83b\x83g\x82̐擪\x82\xC9 uint32 (4\x83o\x83C\x83g) \x82̃p\x83P\x83b\x83g\x92\xB7\x82\xAA\x97\x88\x82\xE9 - pktsize = get_uint32_MSBfirst(data); - if (SSHv1(pvar)) { // SSH1 \x82ł̓p\x83P\x83b\x83g\x92\xB7\x82̒l\x82ɂ\xCD padding \x82̒\xB7\x82\xB3\x82\xAA\x8A܂܂\xEA\x82Ă\xA2\x82Ȃ\xA2\x81B // \x82܂\xBD padding \x82̒\xB7\x82\xB3\x82̏\xEE\x95\xF1\x82\xE0\x83p\x83P\x83b\x83g\x8F\xE3\x82ɂ͖\xB3\x82\xA2\x82̂ŁA\x83p\x83P\x83b\x83g\x92\xB7\x82̒l\x82\xA9\x82\xE7\x8Cv\x8EZ\x82\xB7\x82\xE9\x81B - padding = 8 - (pktsize % 8); + padding_size = 8 - (pktsize % 8); - // \x88ȍ~\x82̏\x88\x97\x9D\x82\xCD pktsize \x82\xC9 padding \x82̒l\x82\xAA\x8A܂܂\xEA\x82Ă\xA2\x82鎖\x82\xAA\x91O\x92\xF1\x82ƂȂ\xC1\x82Ă\xA2\x82\xE9\x81B - pktsize += padding; + // \x88ȍ~\x82̏\x88\x97\x9D\x82\xCD pktsize \x82\xC9 padding_size \x82̒l\x82\xAA\x8A܂܂\xEA\x82Ă\xA2\x82鎖\x82\xAA\x91O\x92\xF1\x82ƂȂ\xC1\x82Ă\xA2\x82\xE9\x81B + pktsize += padding_size; } - // \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+4\x81i+MAC\x81j\x82ƂȂ\xE9\x81B - // +4\x82́ASSH\x83y\x83C\x83\x8D\x81[\x83h\x82̃T\x83C\x83Y\x82\xF0\x8Ai\x94[\x82\xB5\x82Ă\xA2\x82镔\x95\xAA\x81iint\x8C^\x81j\x81B - total_packet_size = pktsize + 4 + SSH_get_authdata_size(pvar, MODE_IN); + // \x83p\x83P\x83b\x83g(TCP\x83y\x83C\x83\x8D\x81[\x83h)\x82̑S\x91̂̃T\x83C\x83Y\x82́A + // 4\x81i\x83p\x83P\x83b\x83g\x92\xB7\x82̃T\x83C\x83Y\x81j+\x83p\x83P\x83b\x83g\x92\xB7\x81i+MAC\x82̃T\x83C\x83Y\x81j\x82ƂȂ\xE9\x81B + total_packet_size = 4 + pktsize + SSH_get_authdata_size(pvar, MODE_IN); if (total_packet_size <= pvar->pkt_state.datalen) { // \x8E\xF3\x90M\x8Dς݃f\x81[\x83^\x82\xAA\x8F\\x95\xAA\x97L\x82\xE9\x8Fꍇ\x82̓p\x83P\x83b\x83g\x82̎\xC0\x8F\x88\x97\x9D\x82\xF0\x8Ds\x82\xA4 if (SSHv1(pvar)) { // SSH1 \x82\xCD EtM \x94\xF1\x91Ή\x9E (\x82\xBB\x82\xE0\x82\xBB\x82\xE0 MAC \x82ł͂Ȃ\xAD CRC \x82\xF0\x8Eg\x82\xA4) - SSH1_handle_packet(pvar, data, pktsize, padding); + SSH1_handle_packet(pvar, data, pktsize, padding_size); } else { // SSH2 \x82ł͂\xB1\x82̎\x9E\x93_\x82ł\xCD padding \x92\xB7\x95\x94\x95\xAA\x82\xAA\x95\x9C\x8D\x86\x82\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x8Fꍇ\x82\xAA\x82\xA0\x82\xE9\x82̂ŁA // padding \x92\xB7\x82͓n\x82\xB3\x82\xB8\x82ɁA\x95K\x97v\x82ɂȂ\xC1\x82\xBD\x8E\x9E\x82ɓ\xE0\x95\x94\x82Ŏ擾\x82\xB7\x82\xE9\x81B - SSH2_handle_packet(pvar, data, pktsize, aadlen, enc->auth_len); + SSH2_handle_packet(pvar, data, pktsize, aadlen, authlen); } pvar->pkt_state.predecrypted_packet = FALSE; Copied: branches/4-stable/ttssh2/ttxssh/poly1305.c (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/poly1305.c) =================================================================== --- branches/4-stable/ttssh2/ttxssh/poly1305.c (rev 0) +++ branches/4-stable/ttssh2/ttxssh/poly1305.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -0,0 +1,165 @@ +/* Imported from OpenSSH-8.5p1, TeraTerm Project */ + +/* + * Public Domain poly1305 from Andrew Moon + * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna + */ + +/* $OpenBSD: poly1305.c,v 1.3 2013/12/19 22:57:13 djm Exp $ */ + +// #include "includes.h" + +// for Visual Studio 2005 +#pragma warning(disable : 4244) + +#include <sys/types.h> +#ifdef HAVE_STDINT_H +# include <stdint.h> +#endif + +#include "poly1305.h" + +#define mul32x32_64(a,b) ((uint64_t)(a) * (b)) + +#define U8TO32_LE(p) \ + (((uint32_t)((p)[0])) | \ + ((uint32_t)((p)[1]) << 8) | \ + ((uint32_t)((p)[2]) << 16) | \ + ((uint32_t)((p)[3]) << 24)) + +#define U32TO8_LE(p, v) \ + do { \ + (p)[0] = (uint8_t)((v)); \ + (p)[1] = (uint8_t)((v) >> 8); \ + (p)[2] = (uint8_t)((v) >> 16); \ + (p)[3] = (uint8_t)((v) >> 24); \ + } while (0) + +void +poly1305_auth(unsigned char out[POLY1305_TAGLEN], const unsigned char *m, size_t inlen, const unsigned char key[POLY1305_KEYLEN]) { + uint32_t t0,t1,t2,t3; + uint32_t h0,h1,h2,h3,h4; + uint32_t r0,r1,r2,r3,r4; + uint32_t s1,s2,s3,s4; + uint32_t b, nb; + size_t j; + uint64_t t[5]; + uint64_t f0,f1,f2,f3; + uint32_t g0,g1,g2,g3,g4; + uint64_t c; + unsigned char mp[16]; + + /* clamp key */ + t0 = U8TO32_LE(key+0); + t1 = U8TO32_LE(key+4); + t2 = U8TO32_LE(key+8); + t3 = U8TO32_LE(key+12); + + /* precompute multipliers */ + r0 = t0 & 0x3ffffff; t0 >>= 26; t0 |= t1 << 6; + r1 = t0 & 0x3ffff03; t1 >>= 20; t1 |= t2 << 12; + r2 = t1 & 0x3ffc0ff; t2 >>= 14; t2 |= t3 << 18; + r3 = t2 & 0x3f03fff; t3 >>= 8; + r4 = t3 & 0x00fffff; + + s1 = r1 * 5; + s2 = r2 * 5; + s3 = r3 * 5; + s4 = r4 * 5; + + /* init state */ + h0 = 0; + h1 = 0; + h2 = 0; + h3 = 0; + h4 = 0; + + /* full blocks */ + if (inlen < 16) goto poly1305_donna_atmost15bytes; +poly1305_donna_16bytes: + m += 16; + inlen -= 16; + + t0 = U8TO32_LE(m-16); + t1 = U8TO32_LE(m-12); + t2 = U8TO32_LE(m-8); + t3 = U8TO32_LE(m-4); + + h0 += t0 & 0x3ffffff; + h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + h4 += (t3 >> 8) | (1 << 24); + + +poly1305_donna_mul: + t[0] = mul32x32_64(h0,r0) + mul32x32_64(h1,s4) + mul32x32_64(h2,s3) + mul32x32_64(h3,s2) + mul32x32_64(h4,s1); + t[1] = mul32x32_64(h0,r1) + mul32x32_64(h1,r0) + mul32x32_64(h2,s4) + mul32x32_64(h3,s3) + mul32x32_64(h4,s2); + t[2] = mul32x32_64(h0,r2) + mul32x32_64(h1,r1) + mul32x32_64(h2,r0) + mul32x32_64(h3,s4) + mul32x32_64(h4,s3); + t[3] = mul32x32_64(h0,r3) + mul32x32_64(h1,r2) + mul32x32_64(h2,r1) + mul32x32_64(h3,r0) + mul32x32_64(h4,s4); + t[4] = mul32x32_64(h0,r4) + mul32x32_64(h1,r3) + mul32x32_64(h2,r2) + mul32x32_64(h3,r1) + mul32x32_64(h4,r0); + + h0 = (uint32_t)t[0] & 0x3ffffff; c = (t[0] >> 26); + t[1] += c; h1 = (uint32_t)t[1] & 0x3ffffff; b = (uint32_t)(t[1] >> 26); + t[2] += b; h2 = (uint32_t)t[2] & 0x3ffffff; b = (uint32_t)(t[2] >> 26); + t[3] += b; h3 = (uint32_t)t[3] & 0x3ffffff; b = (uint32_t)(t[3] >> 26); + t[4] += b; h4 = (uint32_t)t[4] & 0x3ffffff; b = (uint32_t)(t[4] >> 26); + h0 += b * 5; + + if (inlen >= 16) goto poly1305_donna_16bytes; + + /* final bytes */ +poly1305_donna_atmost15bytes: + if (!inlen) goto poly1305_donna_finish; + + for (j = 0; j < inlen; j++) mp[j] = m[j]; + mp[j++] = 1; + for (; j < 16; j++) mp[j] = 0; + inlen = 0; + + t0 = U8TO32_LE(mp+0); + t1 = U8TO32_LE(mp+4); + t2 = U8TO32_LE(mp+8); + t3 = U8TO32_LE(mp+12); + + h0 += t0 & 0x3ffffff; + h1 += ((((uint64_t)t1 << 32) | t0) >> 26) & 0x3ffffff; + h2 += ((((uint64_t)t2 << 32) | t1) >> 20) & 0x3ffffff; + h3 += ((((uint64_t)t3 << 32) | t2) >> 14) & 0x3ffffff; + h4 += (t3 >> 8); + + goto poly1305_donna_mul; + +poly1305_donna_finish: + b = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += b; b = h1 >> 26; h1 = h1 & 0x3ffffff; + h2 += b; b = h2 >> 26; h2 = h2 & 0x3ffffff; + h3 += b; b = h3 >> 26; h3 = h3 & 0x3ffffff; + h4 += b; b = h4 >> 26; h4 = h4 & 0x3ffffff; + h0 += b * 5; b = h0 >> 26; h0 = h0 & 0x3ffffff; + h1 += b; + + g0 = h0 + 5; b = g0 >> 26; g0 &= 0x3ffffff; + g1 = h1 + b; b = g1 >> 26; g1 &= 0x3ffffff; + g2 = h2 + b; b = g2 >> 26; g2 &= 0x3ffffff; + g3 = h3 + b; b = g3 >> 26; g3 &= 0x3ffffff; + g4 = h4 + b - (1 << 26); + + b = (g4 >> 31) - 1; + nb = ~b; + h0 = (h0 & nb) | (g0 & b); + h1 = (h1 & nb) | (g1 & b); + h2 = (h2 & nb) | (g2 & b); + h3 = (h3 & nb) | (g3 & b); + h4 = (h4 & nb) | (g4 & b); + + f0 = ((h0 ) | (h1 << 26)) + (uint64_t)U8TO32_LE(&key[16]); + f1 = ((h1 >> 6) | (h2 << 20)) + (uint64_t)U8TO32_LE(&key[20]); + f2 = ((h2 >> 12) | (h3 << 14)) + (uint64_t)U8TO32_LE(&key[24]); + f3 = ((h3 >> 18) | (h4 << 8)) + (uint64_t)U8TO32_LE(&key[28]); + + U32TO8_LE(&out[ 0], f0); f1 += (f0 >> 32); + U32TO8_LE(&out[ 4], f1); f2 += (f1 >> 32); + U32TO8_LE(&out[ 8], f2); f3 += (f2 >> 32); + U32TO8_LE(&out[12], f3); +} Copied: branches/4-stable/ttssh2/ttxssh/poly1305.h (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/poly1305.h) =================================================================== --- branches/4-stable/ttssh2/ttxssh/poly1305.h (rev 0) +++ branches/4-stable/ttssh2/ttxssh/poly1305.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -0,0 +1,26 @@ +/* Imported from OpenSSH-8.5p1, TeraTerm Project */ + +/* $OpenBSD: poly1305.h,v 1.4 2014/05/02 03:27:54 djm Exp $ */ + +/* + * Public Domain poly1305 from Andrew Moon + * poly1305-donna-unrolled.c from https://github.com/floodyberry/poly1305-donna + */ + +#ifndef POLY1305_H +#define POLY1305_H + +#include <stdio.h> +#include <sys/types.h> +typedef unsigned char u_char; +typedef unsigned char uint8_t; +typedef unsigned int uint32_t; +typedef unsigned long long uint64_t; + +#define POLY1305_KEYLEN 32 +#define POLY1305_TAGLEN 16 + +void poly1305_auth(u_char out[POLY1305_TAGLEN], const u_char *m, size_t inlen, + const u_char key[POLY1305_KEYLEN]); + +#endif /* POLY1305_H */ Modified: branches/4-stable/ttssh2/ttxssh/ssh.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/ssh.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/ssh.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -931,6 +931,7 @@ * data - ssh \x83p\x83P\x83b\x83g\x82̐擪\x82\xF0\x8Ew\x82\xB7\x83|\x83C\x83\x93\x83^ * len - \x83p\x83P\x83b\x83g\x92\xB7 (\x90擪\x82̃p\x83P\x83b\x83g\x92\xB7\x97̈\xE6(4\x83o\x83C\x83g)\x82\xF0\x8F\x9C\x82\xA2\x82\xBD\x92l) * aadlen - \x88Í\x86\x89\xBB\x82\xB3\x82\xEA\x82Ă\xA2\x82Ȃ\xA2\x82\xAA\x94F\x8F̑ΏۂƂȂ\xC1\x82Ă\xA2\x82\xE9\x83f\x81[\x83^\x82̒\xB7\x82\xB3 + * chacha20-poly1305 \x82ł͈Í\x86\x89\xBB\x82\xB3\x82\xEA\x82\xE9\x83p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82̒\xB7\x82\xB3 * authlen - \x94F\x8Ff\x81[\x83^(AEAD tag)\x92\xB7 */ @@ -1175,8 +1176,9 @@ CRYPT_encrypt(pvar, data + 4, data_length - 4); } else { //for SSH2(yutaka) unsigned int block_size = CRYPT_get_encryption_block_size(pvar); + unsigned int packet_length; unsigned int encryption_size; - unsigned int padding; + unsigned int padding_size; BOOL ret; struct Mac *mac = &pvar->ssh2_keys[MODE_OUT].mac; struct Enc *enc = &pvar->ssh2_keys[MODE_OUT].enc; @@ -1189,7 +1191,7 @@ <--ignore---> ^^^^^^^^ <---- payload ---> packet length - ^^padding + ^^padding_size <----------------------------> SSH2 sending data on TCP @@ -1238,32 +1240,37 @@ } if (mac && mac->etm || authlen > 0) { - // \x88Í\x86\x89\xBB\x91Ώۂł͖\xB3\x82\xA2\x82\xAA\x81AMAC \x82̑ΏۂƂȂ镔\x95\xAA\x82̒\xB7\x82\xB3 + // \x88Í\x86\x89\xBB\x91Ώۂł͂Ȃ\xA2\x82\xAA\x81AMAC \x82̑ΏۂƂȂ\xE9\x83p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82̒\xB7\x82\xB3 + // \x82܂\xBD\x82\xCD chacha20-poly1305 \x82ňÍ\x86\x89\xBB\x82\xB3\x82\xEA\x82\xE9\x83p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82̒\xB7\x82\xB3 + // cf. PKT_recv \x93\xE0\x82̃R\x83\x81\x83\x93\x83g 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 + aadlen); - data[4] = (unsigned char) padding; + packet_length = 1 + len; // \x83p\x83f\x83B\x83\x93\x83O\x92\xB7\x82̃T\x83C\x83Y + \x83y\x83C\x83\x8D\x81[\x83h\x92\xB7 + encryption_size = 4 + packet_length - aadlen; // \x83p\x83P\x83b\x83g\x92\xB7\x82̃T\x83C\x83Y + packet_length - addlen + padding_size = block_size - (encryption_size % block_size); + if (padding_size < 4) + padding_size += block_size; + packet_length += padding_size; + encryption_size += padding_size; + set_uint32(data, packet_length); + data[4] = (unsigned char) padding_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); + buffer_append_space(msg, padding_size + EVP_MAX_MD_SIZE); // realloc()\x82\xB3\x82\xEA\x82\xE9\x82ƁA\x83|\x83C\x83\x93\x83^\x82\xAA\x95ς\xED\x82\xE9\x89\\x90\xAB\x82\xAA\x82\xA0\x82\xE9\x82̂ŁA\x8Dēx\x8E\xE6\x82蒼\x82\xB7\x81B data = buffer_ptr(msg); } - CRYPT_set_random_data(pvar, data + 5 + len, padding); + CRYPT_set_random_data(pvar, data + 5 + len, padding_size); if (authlen > 0) { + // \x83p\x83P\x83b\x83g\x88Í\x86\x89\xBB\x82\xC6 MAC \x82̌v\x8EZ CRYPT_encrypt_aead(pvar, data, encryption_size, aadlen, authlen); maclen = authlen; } else if (aadlen) { - // \x83p\x83P\x83b\x83g\x88Í\x86\x89\xBB + // \x83p\x83P\x83b\x83g\x88Í\x86\x89\xBB\x81iaadlen\x82\xE6\x82\xE8\x8C\xE3\x82낾\x82\xAF\x81j CRYPT_encrypt(pvar, data + aadlen, encryption_size); // EtM \x82ł͈Í\x86\x89\xBB\x8C\xE3\x82\xC9 MAC \x82\xF0\x8Cv\x8EZ\x82\xB7\x82\xE9 @@ -1274,7 +1281,7 @@ } } else { - // E&M \x82ł͐\xE6\x82\xC9 MAC \x82\xF0\x8Cv\x8EZ\x82\xB7\x82\xE9 + // E&M \x82ł͈Í\x86\x89\xBB\x91O\x82\xC9 MAC \x82\xF0\x8Cv\x8EZ\x82\xB7\x82\xE9 ret = CRYPT_build_sender_MAC(pvar, pvar->ssh_state.sender_sequence_number, data, encryption_size, data + encryption_size); if (ret) { @@ -1288,9 +1295,12 @@ data_length = encryption_size + aadlen + maclen; logprintf(150, - "%s: built packet info: aadlen:%d, enclen:%d, padlen:%d, datalen:%d, maclen:%d, mode:%s", - __FUNCTION__, - aadlen, encryption_size, padding, data_length, maclen, aadlen ? "EtM" : "E&M"); + "%s: built packet info: " + "aadlen:%d, enclen:%d, padlen:%d, datalen:%d, maclen:%d, " + "Encrypt Mode:%s, MAC mode:%s", + __FUNCTION__, + aadlen, encryption_size, padding_size, data_length, maclen, + authlen ? "AEAD" : "not AEAD", aadlen ? "EtM" : "E&M"); } send_packet_blocking(pvar, data, data_length); @@ -4339,239 +4349,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 +4376,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 +4455,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\x82A\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\x82Adisabled 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 +4575,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 +4581,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 +4647,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 +4730,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 +4796,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 +4824,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 +4941,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 +5569,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 +5671,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 +5834,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 +5943,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 +6107,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 +6215,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; } @@ -6867,6 +6408,7 @@ | 1 << SSH2_CIPHER_CAMELLIA256_CTR | 1 << SSH2_CIPHER_AES128_GCM | 1 << SSH2_CIPHER_AES256_GCM + | 1 << SSH2_CIPHER_CHACHAPOLY ); int type = (1 << SSH_AUTH_PASSWORD) | (1 << SSH_AUTH_RSA) | (1 << SSH_AUTH_TIS) | (1 << SSH_AUTH_PAGEANT); @@ -7091,7 +6633,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 +6651,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/4-stable/ttssh2/ttxssh/ssh.h =================================================================== --- branches/4-stable/ttssh2/ttxssh/ssh.h 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/ssh.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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 */ Copied: branches/4-stable/ttssh2/ttxssh/ssherr.c (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.c) =================================================================== --- branches/4-stable/ttssh2/ttxssh/ssherr.c (rev 0) +++ branches/4-stable/ttssh2/ttxssh/ssherr.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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"; + } +} Copied: branches/4-stable/ttssh2/ttxssh/ssherr.h (from rev 9252, branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssherr.h) =================================================================== --- branches/4-stable/ttssh2/ttxssh/ssherr.h (rev 0) +++ branches/4-stable/ttssh2/ttxssh/ssherr.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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/4-stable/ttssh2/ttxssh/ttxssh.c =================================================================== --- branches/4-stable/ttssh2/ttxssh/ttxssh.c 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/ttxssh.c 2021-05-19 14:11:12 UTC (rev 9254) @@ -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) @@ -155,10 +161,10 @@ FWDUI_init(pvar); ssh_heartbeat_lock_initialize(); - - pvar->evpcip[MODE_IN] = EVP_CIPHER_CTX_new(); - pvar->evpcip[MODE_OUT] = EVP_CIPHER_CTX_new(); - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/ + + pvar->cc[MODE_IN] = NULL; + pvar->cc[MODE_OUT] = NULL; + // \x83\x81\x83\x82\x83\x8A\x8Am\x95ۂ\xCD CRYPT_start_encryption \x82̐\xE6\x82\xCC cipher_init_SSH2 \x82Ɉړ\xAE } static void uninit_TTSSH(PTInstVar pvar) @@ -191,8 +197,12 @@ ssh_heartbeat_lock_finalize(); - EVP_CIPHER_CTX_free(pvar->evpcip[MODE_IN]); - EVP_CIPHER_CTX_free(pvar->evpcip[MODE_OUT]); + cipher_free_SSH2(pvar->cc[MODE_IN]); + cipher_free_SSH2(pvar->cc[MODE_OUT]); + + // CloseTCP \x82\xC6 TTXEnd \x82\xA9\x82\xE7 2 \x89\xF1\x8CĂ\xEA\x82\xE9\x8Fꍇ\x82\xAA\x82\xA0\x82邽\x82߁A2\x8Fd free \x82\xB5\x82Ȃ\xA2\x82悤\x82\xC9 NULL \x82\xF0\x83Z\x83b\x83g\x82\xB5\x82Ă\xA8\x82\xAD + pvar->cc[MODE_IN] = NULL; + pvar->cc[MODE_OUT] = NULL; } static void PASCAL TTXInit(PTTSet ts, PComVar cv) @@ -207,208 +217,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\x82A\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\x82Adisabled 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) { @@ -645,8 +453,8 @@ // Remember password (2006.8.5 yutaka) WritePrivateProfileString("TTSSH", "RememberPassword", - settings->remember_password ? "1" : "0", - fileName); + settings->remember_password ? "1" : "0", + fileName); // \x8F\x89\x89\xF1\x82̔F\x8F_\x83C\x83A\x83\x8D\x83O\x82ŃT\x83|\x81[\x83g\x82\xB3\x82\xEA\x82Ă\xA2\x82郁\x83\\x83b\x83h\x82\xF0\x83`\x83F\x83b\x83N\x82\xB5\x81A // \x96\xB3\x8C\xF8\x82ȃ\x81\x83\\x83b\x83h\x82\xF0\x83O\x83\x8C\x83C\x83A\x83E\x83g\x82\xB7\x82\xE9 (2007.9.24 maya) @@ -1145,10 +953,10 @@ 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) - SSH2_update_cipher_myproposal(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 SSH2_update_kex_myproposal(pvar); SSH2_update_host_key_myproposal(pvar); + SSH2_update_cipher_myproposal(pvar); SSH2_update_hmac_myproposal(pvar); SSH2_update_compression_myproposal(pvar); } @@ -1652,13 +1460,13 @@ static void UTIL_SetDialogFont() { SetDialogFont(pvar->ts->DialogFontName, pvar->ts->DialogFontPoint, pvar->ts->DialogFontCharSet, - pvar->ts->UILanguageFile, "TTSSH", "DLG_TAHOMA_FONT"); + pvar->ts->UILanguageFile, "TTSSH", "DLG_TAHOMA_FONT"); } static BOOL PASCAL TTXGetHostName(HWND parent, PGetHNRec rec) { SetDialogFont(pvar->ts->DialogFontName, pvar->ts->DialogFontPoint, pvar->ts->DialogFontCharSet, - pvar->ts->UILanguageFile, "TTSSH", "DLG_SYSTEM_FONT"); + pvar->ts->UILanguageFile, "TTSSH", "DLG_SYSTEM_FONT"); return (BOOL) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_HOSTDLG), parent, TTXHostDlg, (LPARAM)rec); } @@ -2292,7 +2100,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 +2339,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 +2431,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); @@ -2706,9 +2447,9 @@ int index = pvar->settings.KexOrder[i] - '0'; char *name = NULL; - if (index == 0) { + if (index == 0) { UTIL_get_lang_msg("DLG_SSHSETUP_KEX_BORDER", pvar, - "<KEXs below this line are disabled>"); + "<KEXs below this line are disabled>"); name = pvar->ts->UIMsg; } else { name = get_kex_algorithm_name(index); @@ -2727,12 +2468,12 @@ int index = pvar->settings.HostKeyOrder[i] - '0'; char *name = NULL; - if (index == 0) { + if (index == 0) { UTIL_get_lang_msg("DLG_SSHSETUP_HOST_KEY_BORDER", pvar, - "<Host Keys below this line are disabled>"); + "<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) { @@ -2748,9 +2489,9 @@ int index = pvar->settings.MacOrder[i] - '0'; char *name = NULL; - if (index == 0) { + if (index == 0) { UTIL_get_lang_msg("DLG_SSHSETUP_MAC_BORDER", pvar, - "<MACs below this line are disabled>"); + "<MACs below this line are disabled>"); name = pvar->ts->UIMsg; } else { name = get_ssh2_mac_name_by_id(index); @@ -2769,9 +2510,9 @@ int index = pvar->settings.CompOrder[i] - '0'; char *name = NULL; - if (index == 0) { + if (index == 0) { UTIL_get_lang_msg("DLG_SSHSETUP_COMP_BORDER", pvar, - "<Compression methods below this line are disabled>"); + "<Compression methods below this line are disabled>"); name = pvar->ts->UIMsg; } else { name = get_ssh2_comp_name(index); @@ -2941,7 +2682,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 +2736,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; @@ -3216,7 +2957,7 @@ } static INT_PTR CALLBACK TTXSetupDlg(HWND dlg, UINT msg, WPARAM wParam, - LPARAM lParam) + LPARAM lParam) { switch (msg) { case WM_INITDIALOG: @@ -3538,144 +3279,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; - } - EVP_CIPHER_CTX_init(c->k1); - EVP_CIPHER_CTX_init(c->k2); - EVP_CIPHER_CTX_init(c->k3); - 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_cleanup(c->k1); - EVP_CIPHER_CTX_cleanup(c->k2); - EVP_CIPHER_CTX_cleanup(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]; @@ -4035,7 +3638,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; @@ -4044,7 +3647,7 @@ int blocksize, keylen, ivlen, authlen, i, n; unsigned char *key = NULL, salt[SALT_LEN]; char *kdfname = KDFNAME; - EVP_CIPHER_CTX *cipher_ctx = NULL; + struct sshcipher_ctx *cc = NULL; Key keyblob; unsigned char *cp = NULL; unsigned int len, check; @@ -4055,8 +3658,7 @@ kdf = buffer_init(); encoded = buffer_init(); blob = buffer_init(); - cipher_ctx = EVP_CIPHER_CTX_new(); - if (b == NULL || kdf == NULL || encoded == NULL || blob == NULL || cipher_ctx == NULL) + if (b == NULL || kdf == NULL || encoded == NULL || blob == NULL) goto ed25519_error; if (passphrase == NULL || !strlen(passphrase)) { @@ -4083,8 +3685,8 @@ // \x88Í\x86\x89\xBB\x82̏\x80\x94\xF5 // TODO: OpenSSH 6.5\x82ł\xCD -Z \x83I\x83v\x83V\x83\x87\x83\x93\x82ŁA\x88Í\x86\x89\xBB\x83A\x83\x8B\x83S\x83\x8A\x83Y\x83\x80\x82\xF0\x8Ew\x92\xE8\x89\\x82\xBE\x82\xAA\x81A // \x82\xB1\x82\xB1\x82ł\xCD"AES256-CBC"\x82ɌŒ\xE8\x82Ƃ\xB7\x82\xE9\x81B - cipher_init_SSH2(cipher_ctx, key, keylen, key + keylen, ivlen, CIPHER_ENCRYPT, - get_cipher_EVP_CIPHER(cipher), 0, 0, pvar); + cipher = get_cipher_by_name(ciphername); + cipher_init_SSH2(&cc, cipher, key, keylen, key + keylen, ivlen, CIPHER_ENCRYPT, pvar); SecureZeroMemory(key, keylen + ivlen); free(key); @@ -4127,12 +3729,12 @@ /* encrypt */ cp = buffer_append_space(encoded, buffer_len(b) + authlen); - if (EVP_Cipher(cipher_ctx, cp, buffer_ptr(b), buffer_len(b)) == 0) { + if (EVP_Cipher(cc->evp, cp, buffer_ptr(b), buffer_len(b)) == 0) { //strncpy_s(errmsg, errmsg_len, "Key decrypt error", _TRUNCATE); //free(decrypted); //goto error; } - cipher_cleanup_SSH2(cipher_ctx); + cipher_free_SSH2(cc); len = 2 * buffer_len(encoded); cp = malloc(len); @@ -4182,14 +3784,10 @@ buffer_free(kdf); buffer_free(encoded); buffer_free(blob); - - if (cipher_ctx) { - EVP_CIPHER_CTX_free(cipher_ctx); - } } static INT_PTR CALLBACK TTXKeyGenerator(HWND dlg, UINT msg, WPARAM wParam, - LPARAM lParam) + LPARAM lParam) { static ssh_keytype key_type; static int saved_key_bits; @@ -4637,7 +4235,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)); @@ -4646,7 +4244,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; @@ -4802,7 +4400,8 @@ MD5_CTX md; unsigned char digest[16]; char *passphrase = buf; - EVP_CIPHER_CTX *cipher_ctx = NULL; + const struct ssh2cipher *cipher = NULL; + struct sshcipher_ctx *cc = NULL; FILE *fp; char wrapped[4096]; BIGNUM *e, *n, *d, *dmp1, *dmq1, *iqmp, *p, *q; @@ -4810,7 +4409,7 @@ if (passphrase[0] == '\0') { // passphrase is empty cipher_num = SSH_CIPHER_NONE; } else { - cipher_num = SSH_CIPHER_3DES; // 3DES-CBC + cipher_num = SSH_CIPHER_3DES; // 3DES } b = buffer_init(); @@ -4822,9 +4421,6 @@ break; } - cipher_ctx = EVP_CIPHER_CTX_new(); - /*** TODO: OPENSSL1.1.1 ERROR CHECK(ticket#39335\x82ŏ\x88\x92u\x97\\x92\xE8) ***/ - // set random value rnd = arc4random(); tmp[0] = rnd & 0xff; @@ -4874,9 +4470,11 @@ MD5_Update(&md, (const unsigned char *)passphrase, strlen(passphrase)); MD5_Final(digest, &md); if (cipher_num == SSH_CIPHER_NONE) { - cipher_init_SSH2(cipher_ctx, digest, 16, NULL, 0, CIPHER_ENCRYPT, EVP_enc_null(), 0, 0, pvar); + cipher = get_cipher_by_name("none"); + cipher_init_SSH2(&cc, cipher, digest, 16, NULL, 0, CIPHER_ENCRYPT, pvar); } else { - cipher_init_SSH2(cipher_ctx, digest, 16, NULL, 0, CIPHER_ENCRYPT, evp_ssh1_3des(), 0, 0, pvar); + cipher = get_cipher_by_name("3des"); + cipher_init_SSH2(&cc, cipher, digest, 16, NULL, 0, CIPHER_ENCRYPT, pvar); } len = buffer_len(b); if (len % 8) { // fatal error @@ -4888,12 +4486,9 @@ goto error; } - if (EVP_Cipher(cipher_ctx, wrapped, buffer_ptr(b), len) == 0) { + if (EVP_Cipher(cc->evp, wrapped, buffer_ptr(b), len) == 0) { goto error; } - if (EVP_CIPHER_CTX_cleanup(cipher_ctx) == 0) { - goto error; - } buffer_append(enc, wrapped, len); @@ -4914,14 +4509,12 @@ error:; buffer_free(b); buffer_free(enc); - if (cipher_ctx) { - EVP_CIPHER_CTX_free(cipher_ctx); - } + cipher_free_SSH2(cc); } else if (private_key.type == KEY_ED25519) { // SSH2 ED25519 save_bcrypt_private_key(buf, filename, comment, dlg, pvar, rounds); - } else { // SSH2 RSA, DSA, ECDSA + } else { // SSH2 RSA, DSA, ECDSA int len; FILE *fp; const EVP_CIPHER *cipher; @@ -5082,7 +4675,7 @@ pvar->showing_err = TRUE; pvar->err_msg = NULL; MessageBox(NULL, msg, "TTSSH", - MB_TASKMODAL | MB_ICONEXCLAMATION); + MB_TASKMODAL | MB_ICONEXCLAMATION); free(msg); pvar->showing_err = FALSE; Modified: branches/4-stable/ttssh2/ttxssh/ttxssh.h =================================================================== --- branches/4-stable/ttssh2/ttxssh/ttxssh.h 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/ttxssh.h 2021-05-19 14:11:12 UTC (rev 9254) @@ -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; @@ -278,7 +283,7 @@ char *session_id; int session_id_len; SSHKeys ssh2_keys[MODE_MAX]; - EVP_CIPHER_CTX *evpcip[MODE_MAX]; + struct sshcipher_ctx *cc[MODE_MAX]; int userauth_success; int shell_id; int session_nego_status; Modified: branches/4-stable/ttssh2/ttxssh/ttxssh.v16.vcxproj =================================================================== --- branches/4-stable/ttssh2/ttxssh/ttxssh.v16.vcxproj 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/ttxssh.v16.vcxproj 2021-05-19 14:11:12 UTC (rev 9254) @@ -153,7 +153,11 @@ <ClCompile Include="auth.c" /> <ClCompile Include="buffer.c" /> <ClCompile Include="chacha.c" /> + <ClCompile Include="cipher.c" /> + <ClCompile Include="cipher-3des1.c" /> + <ClCompile Include="cipher-chachapoly-libcrypto.c" /> <ClCompile Include="cipher-ctr.c" /> + <ClCompile Include="comp.c" /> <ClCompile Include="crypt.c" /> <ClCompile Include="dns.c" /> <ClCompile Include="ed25519.c" /> @@ -168,13 +172,17 @@ <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="poly1305.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 +194,8 @@ <ClInclude Include="buffer.h" /> <ClInclude Include="chacha.h" /> <ClInclude Include="cipher.h" /> + <ClInclude Include="cipher-chachapoly.h" /> + <ClInclude Include="comp.h" /> <ClInclude Include="config.h" /> <ClInclude Include="crypt.h" /> <ClInclude Include="dns.h" /> @@ -197,14 +207,18 @@ <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="poly1305.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/4-stable/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters =================================================================== --- branches/4-stable/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/ttxssh.v16.vcxproj.filters 2021-05-19 14:11:12 UTC (rev 9254) @@ -13,9 +13,21 @@ <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-chachapoly-libcrypto.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 +70,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 +85,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> @@ -76,6 +94,9 @@ <ClCompile Include="pkt.c"> <Filter>Source Files</Filter> </ClCompile> + <ClCompile Include="poly1305.c"> + <Filter>Source Files</Filter> + </ClCompile> <ClCompile Include="sftp.c"> <Filter>Source Files</Filter> </ClCompile> @@ -82,6 +103,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> @@ -141,9 +165,15 @@ <ClInclude Include="cipher.h"> <Filter>Header Files</Filter> </ClInclude> + <ClInclude Include="cipher-chachapoly.h"> + <Filter>Header Files</Filter> + </ClInclude> <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 +201,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,9 +216,15 @@ <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> + <ClInclude Include="poly1305.h"> + <Filter>Header Files</Filter> + </ClInclude> <ClInclude Include="sftp.h"> <Filter>Header Files</Filter> </ClInclude> @@ -192,6 +231,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/4-stable/ttssh2/ttxssh/ttxssh.v8.vcproj =================================================================== --- branches/4-stable/ttssh2/ttxssh/ttxssh.v8.vcproj 2021-05-19 14:05:07 UTC (rev 9253) +++ branches/4-stable/ttssh2/ttxssh/ttxssh.v8.vcproj 2021-05-19 14:11:12 UTC (rev 9254) @@ -236,10 +236,18 @@ > </File> <File + RelativePath="cipher-chachapoly.h" + > + </File> + <File RelativePath="..\..\teraterm\common\codeconv.h" > </File> <File + RelativePath="comp.h" + > + </File> + <File RelativePath="config.h" > </File> @@ -284,6 +292,10 @@ > </File> <File + RelativePath="hostkey.h" + > + </File> + <File RelativePath="hosts.h" > </File> @@ -300,10 +312,18 @@ > </File> <File + RelativePath="mac.h" + > + </File> + <File RelativePath="pkt.h" > </File> <File + RelativePath="poly1305.h" + > + </File> + <File RelativePath="resource.h" > </File> @@ -316,6 +336,10 @@ > </File> <File + RelativePath="ssherr.h" + > + </File> + <File RelativePath="ttxssh-version.h" > </File> @@ -352,6 +376,18 @@ > </File> <File + RelativePath="cipher.c" + > + </File> + <File + RelativePath="cipher-3des1.c" + > + </File> + <File + RelativePath="cipher-chachapoly-libcrypto.c" + > + </File> + <File RelativePath="cipher-ctr.c" > </File> @@ -360,6 +396,10 @@ > </File> <File + RelativePath="comp.c" + > + </File> + <File RelativePath="crypt.c" > </File> @@ -428,6 +468,10 @@ > </File> <File + RelativePath="hostkey.c" + > + </File> + <File RelativePath="hosts.c" > </File> @@ -444,6 +488,10 @@ > </File> <File + RelativePath="mac.c" + > + </File> + <File RelativePath="..\matcher\matcher.c" > </File> @@ -452,6 +500,10 @@ > </File> <File + RelativePath="poly1305.c" + > + </File> + <File RelativePath="sftp.c" > </File> @@ -460,6 +512,10 @@ > </File> <File + RelativePath="ssherr.c" + > + </File> + <File RelativePath="..\..\teraterm\common\tipwin.cpp" > </File>