Revision: 9217 https://osdn.net/projects/ttssh2/scm/svn/commits/9217 Author: nmaya Date: 2021-04-25 11:18:41 +0900 (Sun, 25 Apr 2021) Log Message: ----------- SSH2 暗号化方式 chach****@opens***** をサポート Modified Paths: -------------- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/pkt.c branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c -------------- next part -------------- Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c 2021-04-24 12:28:27 UTC (rev 9216) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.c 2021-04-25 02:18:41 UTC (rev 9217) @@ -70,6 +70,7 @@ #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 }; @@ -119,7 +120,7 @@ u_int get_cipher_iv_len(const struct ssh2cipher *cipher) { if (cipher) { - if (cipher->iv_len != 0) { + if (cipher->iv_len != 0 || cipher->id != SSH2_CIPHER_CHACHAPOLY) { return cipher->iv_len; } else { @@ -240,6 +241,8 @@ return "aes12****@opens*****"; case SSH2_CIPHER_AES256_GCM: return "aes25****@opens*****"; + case SSH2_CIPHER_CHACHAPOLY: + return "chach****@opens*****(SSH2)"; default: return "Unknown"; @@ -308,6 +311,8 @@ return "aes12****@opens*****(SSH2)"; case SSH2_CIPHER_AES256_GCM: return "aes25****@opens*****(SSH2)"; + case SSH2_CIPHER_CHACHAPOLY: + return "chach****@opens*****(SSH2)"; default: return NULL; @@ -325,6 +330,7 @@ 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, @@ -473,6 +479,9 @@ case SSH2_CIPHER_AES256_GCM: c_str = "aes25****@opens*****,"; break; + case SSH2_CIPHER_CHACHAPOLY: + c_str = "chach****@opens*****,"; + break; default: continue; } @@ -527,10 +536,20 @@ } 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, 4); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 5); notify_fatal_error(pvar, tmp, TRUE); ret = SSH_ERR_ALLOC_FAIL; goto out; @@ -537,7 +556,7 @@ } 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, 5); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 6); notify_fatal_error(pvar, tmp, TRUE); ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; @@ -545,7 +564,7 @@ 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, 6); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 7); notify_fatal_error(pvar, tmp, TRUE); ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; @@ -554,7 +573,7 @@ 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, 7); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 8); notify_fatal_error(pvar, tmp, TRUE); ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; @@ -562,7 +581,7 @@ } 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, 8); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 9); notify_fatal_error(pvar, tmp, TRUE); ret = SSH_ERR_LIBCRYPTO_ERROR; goto out; @@ -574,7 +593,7 @@ 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, 9); + _snprintf_s(tmp, sizeof(tmp), _TRUNCATE, pvar->ts->UIMsg, 10); notify_fatal_error(pvar, tmp, TRUE); } else { @@ -605,6 +624,10 @@ { 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/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h 2021-04-24 12:28:27 UTC (rev 9216) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/cipher.h 2021-04-25 02:18:41 UTC (rev 9217) @@ -43,6 +43,8 @@ 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. @@ -95,12 +97,16 @@ 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; - // struct chachapoly_ctx *cp_ctx; + 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; }; Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c 2021-04-24 12:28:27 UTC (rev 9216) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/crypt.c 2021-04-25 02:18:41 UTC (rev 9217) @@ -205,6 +205,7 @@ unsigned char lastiv[1]; char tmp[80]; struct sshcipher_ctx *cc = pvar->cc[MODE_OUT]; + unsigned int newbuff_len = bytes; if (bytes == 0) return TRUE; @@ -218,13 +219,28 @@ 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 (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; @@ -231,6 +247,7 @@ if (aadlen && !EVP_Cipher(cc->evp, NULL, data, aadlen) < 0) goto err; + // 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; @@ -258,7 +275,8 @@ unsigned int block_size = pvar->ssh2_keys[MODE_IN].enc.block_size; unsigned char lastiv[1]; char tmp[80]; - struct sshcipher_ctx *cc = pvar->cc[MODE_OUT]; + struct sshcipher_ctx *cc = pvar->cc[MODE_IN]; + unsigned int newbuff_len = bytes; if (bytes == 0) return TRUE; @@ -272,13 +290,26 @@ 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 (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; @@ -288,6 +319,7 @@ if (aadlen && !EVP_Cipher(cc->evp, NULL, data, aadlen) < 0) goto err; + // 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; @@ -593,6 +625,7 @@ | (1 << SSH2_CIPHER_CAMELLIA256_CTR) | (1 << SSH2_CIPHER_AES128_GCM) | (1 << SSH2_CIPHER_AES256_GCM) + | (1 << SSH2_CIPHER_CHACHAPOLY) ); } Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/pkt.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/pkt.c 2021-04-24 12:28:27 UTC (rev 9216) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/pkt.c 2021-04-25 02:18:41 UTC (rev 9217) @@ -176,59 +176,111 @@ } 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; /* + * | | 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) aadlen is 4, but lead 4 bytes are encrypted separately from main part. + * (2) implicit MAC type is EtM + */ + + if (enc && enc->auth_len > 0) { + authlen = enc->auth_len; + } + + /* * 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 + * \x82܂\xBD\x82\xCD AEAD \x82\xCC 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 * - * 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 + * EtM \x95\xFB\x8E\xAE\x82\xCC MAC \x82\xE2\x81AAEAD \x82\xCC AES-GCM \x82ł̓p\x83P\x83b\x83g\x82̐擪\x82̃p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82\xCD + * \x88Í\x86\x89\xBB\x82\xB3\x82\xEA\x82Ă\xA8\x82炸\x94F\x8F݂̂\xAA\x8Ds\x82\xED\x82\xEA\x82\xE9\x81B + * AEAD \x82\xCC chacha20-poly1305 \x82ł̓p\x83P\x83b\x83g\x92\xB7\x95\x94\x95\xAA\x82͈Í\x86\x89\xBB\x82\xB3\x82\xEA\x82Ă\xA2\x82邪\x81A + * \x91\xB1\x82\xAD\x95\x94\x95\xAA\x82Ƃ͕ʁX\x82ɈÍ\x86\x89\xBB\x82\xB3\x82\xEA\x82Ă\xA2\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))) { + if (SSHv2(pvar) && ((mac && mac->etm) || authlen > 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 (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\xE0\x88Í\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 Modified: branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c =================================================================== --- branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c 2021-04-24 12:28:27 UTC (rev 9216) +++ branches/ssh_chacha20poly1305/ttssh2/ttxssh/ssh.c 2021-04-25 02:18:41 UTC (rev 9217) @@ -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); @@ -6398,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);