Develop and Download Open Source Software

Browse Subversion Repository

Diff of /branches/ssh_chacha20poly1305/ttssh2/ttxssh/pkt.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 9216 by nmaya, Sat Apr 17 06:15:51 2021 UTC revision 9217 by nmaya, Sun Apr 25 02:18:41 2021 UTC
# Line 176  int PKT_recv(PTInstVar pvar, char *buf, Line 176  int PKT_recv(PTInstVar pvar, char *buf,
176                  }                  }
177                  else if (pvar->pkt_state.seen_server_ID && pvar->pkt_state.datalen >= SSH_get_min_packet_size(pvar)) {                  else if (pvar->pkt_state.seen_server_ID && pvar->pkt_state.datalen >= SSH_get_min_packet_size(pvar)) {
178                          char *data = pvar->pkt_state.buf + pvar->pkt_state.datastart;                          char *data = pvar->pkt_state.buf + pvar->pkt_state.datastart;
179                          uint32 padding;                          uint32 padding_size = 0;
180                          uint32 pktsize;                          uint32 pktsize = 0;
181                          uint32 total_packet_size;                          uint32 total_packet_size;
182                          struct Mac *mac = &pvar->ssh2_keys[MODE_IN].mac;                          struct Mac *mac = &pvar->ssh2_keys[MODE_IN].mac;
183                          struct Enc *enc = &pvar->ssh2_keys[MODE_IN].enc;                          struct Enc *enc = &pvar->ssh2_keys[MODE_IN].enc;
184                          int aadlen;                          int authlen = 0, aadlen = 0;
185    
186                            /*
187                             *                      |          | lead 4 bytes are encrypted | aadlen |
188                             * Encryption type
189                             *   enc->auth_len >  0 | AEAD     | AES-GCM ... no             | 4      |     (2)
190                             *                      |          | chacha20-poly1305 ... yes  | 4      | (1) (2)
191                             *   enc->auth_len == 0 | not AEAD | depends on MAC type        | <-     |
192                             * MAC type
193                             *   mac->etm == true   | EtM      | no                         | 4      |
194                             *   mac->etm == false  | E&M      | yes                        | 0      |
195                             * (1) aadlen is 4, but lead 4 bytes are encrypted separately from main part.
196                             * (2) implicit MAC type is EtM
197                             */
198    
199                            if (enc && enc->auth_len > 0) {
200                                    authlen = enc->auth_len;
201                            }
202    
203                          /*                          /*
204                           * aadlen: Additional Authenticated Data Length                           * aadlen: Additional Authenticated Data Length
205                           *   - 暗号化しないが MAC や AEAD での認証の対象となるデータの長さ                           *   - 暗号化しないが MAC や AEAD での認証の対象となるデータの長さ
206                             *     または AEAD の chacha20-poly1305 で暗号化されるパケット長部分の長さ
207                           *                           *
208                           * EtM 方式の MAC や、AEAD な暗号ではパケットの先頭のパケット長部分は暗号化されず                           * EtM 方式の MAC や、AEAD の AES-GCM ではパケットの先頭のパケット長部分は
209                           * 認証のみが行われる。パケット長は uint32 (4バイト) で格納されている。                           * 暗号化されておらず認証のみが行われる。
210                             * AEAD の chacha20-poly1305 ではパケット長部分は暗号化されているが、
211                             * 続く部分とは別々に暗号化されている。
212                             * パケット長は uint32 (4バイト) で格納されている。
213                           * 通常の MAC 方式 (E&M) で、かつ AEAD でない暗号方式ではパケット長部分も暗号化                           * 通常の MAC 方式 (E&M) で、かつ AEAD でない暗号方式ではパケット長部分も暗号化
214                           * されるので aadlen は 0 となる。                           * されるので aadlen は 0 となる。
215                           */                           */
216                          if (SSHv2(pvar) && ((mac && mac->etm) || (enc && enc->auth_len > 0))) {                          if (SSHv2(pvar) && ((mac && mac->etm) || authlen > 0)) {
217                                  aadlen = 4;                                  aadlen = 4;
218                          }                          }
                         else {  
                                 aadlen = 0;  
                         }  
219    
220                          /*                          if (SSHv2(pvar)) {
221                           * aadlen が 0 の時はパケット長部分が暗号化されている。パケット全体を受信してから                                  /*
222                           * 後段の処理を行う為にパケット長を知る必要が有る為、先頭の 1 ブロックを復号する。                                   * pktsize
223                           */                                   *   uint32   packet_length
224                          if (SSHv2(pvar) && !pvar->pkt_state.predecrypted_packet && aadlen == 0) {                                   * は
225                                  SSH_predecrypt_packet(pvar, data);                                   *   byte     padding_length
226                                  pvar->pkt_state.predecrypted_packet = TRUE;                                   *   byte[n1] payload; n1 = packet_length - padding_length - 1
227                          }                                   *   byte[n2] random padding; n2 = padding_length
228                                     * の長さの合計で
229                                     *   byte[m]  mac (Message Authentication Code - MAC); m = mac_length
230                                     * の長さを含まない。
231                                     * cf. RFC 4253 6. Binary Packet Protocol
232                                     */
233                                    if (authlen > 0 &&
234                                        pvar->cc[MODE_IN]->cipher->id == SSH2_CIPHER_CHACHAPOLY) {
235                                            /*
236                                             * AEAD の chacha20-poly1305 ではパケット長部分も暗号化されている。
237                                             * この処理では長さを取得するが、data は暗号化されたままとなる。
238                                             */
239                                            chachapoly_get_length(pvar->cc[MODE_IN]->cp_ctx, &pktsize,
240                                                                  pvar->ssh_state.receiver_sequence_number,
241                                                                  data, pvar->pkt_state.datalen);
242                                    }
243                                    else if (authlen == 0 &&
244                                             aadlen == 0 &&
245                                             !pvar->pkt_state.predecrypted_packet && aadlen == 0) {
246                                            /*
247                                             * AEAD でなく E&M (aadlen が 0) の時は、暗号化されているパケット長を
248                                             * 知る必要が有るため、先頭の 1 ブロックだけ事前に復号する。
249                                             */
250                                            SSH_predecrypt_packet(pvar, data);
251                                            pvar->pkt_state.predecrypted_packet = TRUE;
252    
253                          // パケットの先頭に uint32 (4バイト) のパケット長が来る                                          pktsize = get_uint32_MSBfirst(data);
254                          pktsize = get_uint32_MSBfirst(data);                                  }
255                                    else {
256                                            /*
257                                             * EtM 方式の MAC や、AEAD で AES-GCM のときなどはそのまま読める。
258                                             */
259                                            pktsize = get_uint32_MSBfirst(data);
260                                    }
261                            }
262                            else {
263                                    pktsize = get_uint32_MSBfirst(data);
264                            }
265    
266                          if (SSHv1(pvar)) {                          if (SSHv1(pvar)) {
267                                  // SSH1 ではパケット長の値には padding の長さが含まれていない。                                  // SSH1 ではパケット長の値には padding の長さが含まれていない。
268                                  // また padding の長さの情報もパケット上には無いので、パケット長の値から計算する。                                  // また padding の長さの情報もパケット上には無いので、パケット長の値から計算する。
269                                  padding = 8 - (pktsize % 8);                                  padding_size = 8 - (pktsize % 8);
270    
271                                  // 以降の処理は pktsize に padding の値が含まれている事が前提となっている。                                  // 以降の処理は pktsize に padding_size の値が含まれている事が前提となっている。
272                                  pktsize += padding;                                  pktsize += padding_size;
273                          }                          }
274    
275                          // パケット(TCPペイロード)の全体のサイズは、SSHペイロード+4(+MAC)となる。                          // パケット(TCPペイロード)の全体のサイズは、
276                          // +4は、SSHペイロードのサイズを格納している部分(int型)。                          // 4(パケット長のサイズ)+パケット長(+MACのサイズ)となる。
277                          total_packet_size = pktsize + 4 + SSH_get_authdata_size(pvar, MODE_IN);                          total_packet_size = 4 + pktsize + SSH_get_authdata_size(pvar, MODE_IN);
278    
279                          if (total_packet_size <= pvar->pkt_state.datalen) {                          if (total_packet_size <= pvar->pkt_state.datalen) {
280                                  // 受信済みデータが十分有る場合はパケットの実処理を行う                                  // 受信済みデータが十分有る場合はパケットの実処理を行う
281                                  if (SSHv1(pvar)) {                                  if (SSHv1(pvar)) {
282                                          // SSH1 は EtM 非対応 (そもそも MAC ではなく CRC を使う)                                          // SSH1 は EtM 非対応 (そもそも MAC ではなく CRC を使う)
283                                          SSH1_handle_packet(pvar, data, pktsize, padding);                                          SSH1_handle_packet(pvar, data, pktsize, padding_size);
284                                  }                                  }
285                                  else {                                  else {
286                                          // SSH2 ではこの時点では padding 長部分が復号されていない場合があるので、                                          // SSH2 ではこの時点では padding 長部分が復号されていない場合があるので、

Legend:
Removed from v.9216  
changed lines
  Added in v.9217

Back to OSDN">Back to OSDN
ViewVC Help
Powered by ViewVC 1.1.26