1 /* 2 * Dropbear SSH 3 * 4 * Copyright (c) 2002-2004 Matt Johnston 5 * Portions Copyright (c) 2004 by Mihnea Stoenescu 6 * All rights reserved. 7 * 8 * Permission is hereby granted, free of charge, to any person obtaining a copy 9 * of this software and associated documentation files (the "Software"), to deal 10 * in the Software without restriction, including without limitation the rights 11 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 12 * copies of the Software, and to permit persons to whom the Software is 13 * furnished to do so, subject to the following conditions: 14 * 15 * The above copyright notice and this permission notice shall be included in 16 * all copies or substantial portions of the Software. 17 * 18 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 19 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 20 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 21 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 22 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 23 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 24 * SOFTWARE. */ 25 26 #include "includes.h" 27 #include "dbutil.h" 28 #include "algo.h" 29 #include "buffer.h" 30 #include "session.h" 31 #include "kex.h" 32 #include "ssh.h" 33 #include "packet.h" 34 #include "bignum.h" 35 #include "random.h" 36 37 /* diffie-hellman-group1-sha1 value for p */ 38 static const unsigned char dh_p_val[] = { 39 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC9, 0x0F, 0xDA, 0xA2, 40 0x21, 0x68, 0xC2, 0x34, 0xC4, 0xC6, 0x62, 0x8B, 0x80, 0xDC, 0x1C, 0xD1, 41 0x29, 0x02, 0x4E, 0x08, 0x8A, 0x67, 0xCC, 0x74, 0x02, 0x0B, 0xBE, 0xA6, 42 0x3B, 0x13, 0x9B, 0x22, 0x51, 0x4A, 0x08, 0x79, 0x8E, 0x34, 0x04, 0xDD, 43 0xEF, 0x95, 0x19, 0xB3, 0xCD, 0x3A, 0x43, 0x1B, 0x30, 0x2B, 0x0A, 0x6D, 44 0xF2, 0x5F, 0x14, 0x37, 0x4F, 0xE1, 0x35, 0x6D, 0x6D, 0x51, 0xC2, 0x45, 45 0xE4, 0x85, 0xB5, 0x76, 0x62, 0x5E, 0x7E, 0xC6, 0xF4, 0x4C, 0x42, 0xE9, 46 0xA6, 0x37, 0xED, 0x6B, 0x0B, 0xFF, 0x5C, 0xB6, 0xF4, 0x06, 0xB7, 0xED, 47 0xEE, 0x38, 0x6B, 0xFB, 0x5A, 0x89, 0x9F, 0xA5, 0xAE, 0x9F, 0x24, 0x11, 48 0x7C, 0x4B, 0x1F, 0xE6, 0x49, 0x28, 0x66, 0x51, 0xEC, 0xE6, 0x53, 0x81, 49 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}; 50 #define DH_P_LEN sizeof(dh_p_val) 51 52 static const int DH_G_VAL = 2; 53 54 static void kexinitialise(); 55 void gen_new_keys(); 56 #ifndef DISABLE_ZLIB 57 static void gen_new_zstreams(); 58 #endif 59 static void read_kex_algos(); 60 /* helper function for gen_new_keys */ 61 static void hashkeys(unsigned char *out, int outlen, 62 const hash_state * hs, unsigned const char X); 63 64 65 /* Send our list of algorithms we can use */ 66 void send_msg_kexinit() { 67 68 CHECKCLEARTOWRITE(); 69 buf_putbyte(ses.writepayload, SSH_MSG_KEXINIT); 70 71 /* cookie */ 72 genrandom(buf_getwriteptr(ses.writepayload, 16), 16); 73 buf_incrwritepos(ses.writepayload, 16); 74 75 /* kex algos */ 76 buf_put_algolist(ses.writepayload, sshkex); 77 78 /* server_host_key_algorithms */ 79 buf_put_algolist(ses.writepayload, sshhostkey); 80 81 /* encryption_algorithms_client_to_server */ 82 buf_put_algolist(ses.writepayload, sshciphers); 83 84 /* encryption_algorithms_server_to_client */ 85 buf_put_algolist(ses.writepayload, sshciphers); 86 87 /* mac_algorithms_client_to_server */ 88 buf_put_algolist(ses.writepayload, sshhashes); 89 90 /* mac_algorithms_server_to_client */ 91 buf_put_algolist(ses.writepayload, sshhashes); 92 93 /* compression_algorithms_client_to_server */ 94 buf_put_algolist(ses.writepayload, sshcompress); 95 96 /* compression_algorithms_server_to_client */ 97 buf_put_algolist(ses.writepayload, sshcompress); 98 99 /* languages_client_to_server */ 100 buf_putstring(ses.writepayload, "", 0); 101 102 /* languages_server_to_client */ 103 buf_putstring(ses.writepayload, "", 0); 104 105 /* first_kex_packet_follows - unimplemented for now */ 106 buf_putbyte(ses.writepayload, 0x00); 107 108 /* reserved unit32 */ 109 buf_putint(ses.writepayload, 0); 110 111 /* set up transmitted kex packet buffer for hashing. 112 * This is freed after the end of the kex */ 113 ses.transkexinit = buf_newcopy(ses.writepayload); 114 115 encrypt_packet(); 116 ses.dataallowed = 0; /* don't send other packets during kex */ 117 118 TRACE(("DATAALLOWED=0")) 119 TRACE(("-> KEXINIT")) 120 ses.kexstate.sentkexinit = 1; 121 } 122 123 /* *** NOTE regarding (send|recv)_msg_newkeys *** 124 * Changed by mihnea from the original kex.c to set dataallowed after a 125 * completed key exchange, no matter the order in which it was performed. 126 * This enables client mode without affecting server functionality. 127 */ 128 129 /* Bring new keys into use after a key exchange, and let the client know*/ 130 void send_msg_newkeys() { 131 132 TRACE(("enter send_msg_newkeys")) 133 134 /* generate the kexinit request */ 135 CHECKCLEARTOWRITE(); 136 buf_putbyte(ses.writepayload, SSH_MSG_NEWKEYS); 137 encrypt_packet(); 138 139 140 /* set up our state */ 141 if (ses.kexstate.recvnewkeys) { 142 TRACE(("while RECVNEWKEYS=1")) 143 gen_new_keys(); 144 kexinitialise(); /* we've finished with this kex */ 145 TRACE((" -> DATAALLOWED=1")) 146 ses.dataallowed = 1; /* we can send other packets again now */ 147 ses.kexstate.donefirstkex = 1; 148 } else { 149 ses.kexstate.sentnewkeys = 1; 150 TRACE(("SENTNEWKEYS=1")) 151 } 152 153 TRACE(("-> MSG_NEWKEYS")) 154 TRACE(("leave send_msg_newkeys")) 155 } 156 157 /* Bring the new keys into use after a key exchange */ 158 void recv_msg_newkeys() { 159 160 TRACE(("<- MSG_NEWKEYS")) 161 TRACE(("enter recv_msg_newkeys")) 162 163 /* simply check if we've sent SSH_MSG_NEWKEYS, and if so, 164 * switch to the new keys */ 165 if (ses.kexstate.sentnewkeys) { 166 TRACE(("while SENTNEWKEYS=1")) 167 gen_new_keys(); 168 kexinitialise(); /* we've finished with this kex */ 169 TRACE((" -> DATAALLOWED=1")) 170 ses.dataallowed = 1; /* we can send other packets again now */ 171 ses.kexstate.donefirstkex = 1; 172 } else { 173 TRACE(("RECVNEWKEYS=1")) 174 ses.kexstate.recvnewkeys = 1; 175 } 176 177 TRACE(("leave recv_msg_newkeys")) 178 } 179 180 181 /* Set up the kex for the first time */ 182 void kexfirstinitialise() { 183 184 ses.kexstate.donefirstkex = 0; 185 kexinitialise(); 186 } 187 188 /* Reset the kex state, ready for a new negotiation */ 189 static void kexinitialise() { 190 191 struct timeval tv; 192 193 TRACE(("kexinitialise()")) 194 195 /* sent/recv'd MSG_KEXINIT */ 196 ses.kexstate.sentkexinit = 0; 197 ses.kexstate.recvkexinit = 0; 198 199 /* sent/recv'd MSG_NEWKEYS */ 200 ses.kexstate.recvnewkeys = 0; 201 ses.kexstate.sentnewkeys = 0; 202 203 /* first_packet_follows */ 204 ses.kexstate.firstfollows = 0; 205 206 ses.kexstate.datatrans = 0; 207 ses.kexstate.datarecv = 0; 208 209 if (gettimeofday(&tv, 0) < 0) { 210 dropbear_exit("Error getting time"); 211 } 212 ses.kexstate.lastkextime = tv.tv_sec; 213 214 } 215 216 /* Helper function for gen_new_keys, creates a hash. It makes a copy of the 217 * already initialised hash_state hs, which should already have processed 218 * the dh_K and hash, since these are common. X is the letter 'A', 'B' etc. 219 * out must have at least min(SHA1_HASH_SIZE, outlen) bytes allocated. 220 * The output will only be expanded once, as we are assured that 221 * outlen <= 2*SHA1_HASH_SIZE for all known hashes. 222 * 223 * See Section 7.2 of rfc4253 (ssh transport) for details */ 224 static void hashkeys(unsigned char *out, int outlen, 225 const hash_state * hs, const unsigned char X) { 226 227 hash_state hs2; 228 unsigned char k2[SHA1_HASH_SIZE]; /* used to extending */ 229 230 memcpy(&hs2, hs, sizeof(hash_state)); 231 sha1_process(&hs2, &X, 1); 232 sha1_process(&hs2, ses.session_id, SHA1_HASH_SIZE); 233 sha1_done(&hs2, out); 234 if (SHA1_HASH_SIZE < outlen) { 235 /* need to extend */ 236 memcpy(&hs2, hs, sizeof(hash_state)); 237 sha1_process(&hs2, out, SHA1_HASH_SIZE); 238 sha1_done(&hs2, k2); 239 memcpy(&out[SHA1_HASH_SIZE], k2, outlen - SHA1_HASH_SIZE); 240 } 241 } 242 243 /* Generate the actual encryption/integrity keys, using the results of the 244 * key exchange, as specified in section 5.2 of the IETF secsh-transport 245 * draft. This occurs after the DH key-exchange. 246 * 247 * ses.newkeys is the new set of keys which are generated, these are only 248 * taken into use after both sides have sent a newkeys message */ 249 250 /* Originally from kex.c, generalized for cli/svr mode --mihnea */ 251 void gen_new_keys() { 252 253 unsigned char C2S_IV[MAX_IV_LEN]; 254 unsigned char C2S_key[MAX_KEY_LEN]; 255 unsigned char S2C_IV[MAX_IV_LEN]; 256 unsigned char S2C_key[MAX_KEY_LEN]; 257 /* unsigned char key[MAX_KEY_LEN]; */ 258 unsigned char *trans_IV, *trans_key, *recv_IV, *recv_key; 259 260 hash_state hs; 261 unsigned int C2S_keysize, S2C_keysize; 262 char mactransletter, macrecvletter; /* Client or server specific */ 263 int recv_cipher = 0, trans_cipher = 0; 264 265 TRACE(("enter gen_new_keys")) 266 /* the dh_K and hash are the start of all hashes, we make use of that */ 267 268 sha1_init(&hs); 269 sha1_process_mp(&hs, ses.dh_K); 270 mp_clear(ses.dh_K); 271 m_free(ses.dh_K); 272 sha1_process(&hs, ses.hash, SHA1_HASH_SIZE); 273 m_burn(ses.hash, SHA1_HASH_SIZE); 274 275 if (IS_DROPBEAR_CLIENT) { 276 trans_IV = C2S_IV; 277 recv_IV = S2C_IV; 278 trans_key = C2S_key; 279 recv_key = S2C_key; 280 C2S_keysize = ses.newkeys->trans_algo_crypt->keysize; 281 S2C_keysize = ses.newkeys->recv_algo_crypt->keysize; 282 mactransletter = 'E'; 283 macrecvletter = 'F'; 284 } else { 285 trans_IV = S2C_IV; 286 recv_IV = C2S_IV; 287 trans_key = S2C_key; 288 recv_key = C2S_key; 289 C2S_keysize = ses.newkeys->recv_algo_crypt->keysize; 290 S2C_keysize = ses.newkeys->trans_algo_crypt->keysize; 291 mactransletter = 'F'; 292 macrecvletter = 'E'; 293 } 294 295 hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); 296 hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); 297 hashkeys(C2S_key, C2S_keysize, &hs, 'C'); 298 hashkeys(S2C_key, S2C_keysize, &hs, 'D'); 299 300 recv_cipher = find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name); 301 if (recv_cipher < 0) 302 dropbear_exit("crypto error"); 303 304 if (cbc_start(recv_cipher, recv_IV, recv_key, 305 ses.newkeys->recv_algo_crypt->keysize, 0, 306 &ses.newkeys->recv_symmetric_struct) != CRYPT_OK) { 307 dropbear_exit("crypto error"); 308 } 309 trans_cipher = find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name); 310 if (trans_cipher < 0) 311 dropbear_exit("crypto error"); 312 313 if (cbc_start(trans_cipher, trans_IV, trans_key, 314 ses.newkeys->trans_algo_crypt->keysize, 0, 315 &ses.newkeys->trans_symmetric_struct) != CRYPT_OK) { 316 dropbear_exit("crypto error"); 317 } 318 319 /* MAC keys */ 320 hashkeys(ses.newkeys->transmackey, 321 ses.newkeys->trans_algo_mac->keysize, &hs, mactransletter); 322 hashkeys(ses.newkeys->recvmackey, 323 ses.newkeys->recv_algo_mac->keysize, &hs, macrecvletter); 324 325 #ifndef DISABLE_ZLIB 326 gen_new_zstreams(); 327 #endif 328 329 /* Switch over to the new keys */ 330 m_burn(ses.keys, sizeof(struct key_context)); 331 m_free(ses.keys); 332 ses.keys = ses.newkeys; 333 ses.newkeys = NULL; 334 335 TRACE(("leave gen_new_keys")) 336 } 337 338 #ifndef DISABLE_ZLIB 339 /* Set up new zlib compression streams, close the old ones. Only 340 * called from gen_new_keys() */ 341 static void gen_new_zstreams() { 342 343 /* create new zstreams */ 344 if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB) { 345 ses.newkeys->recv_zstream = (z_streamp)m_malloc(sizeof(z_stream)); 346 ses.newkeys->recv_zstream->zalloc = Z_NULL; 347 ses.newkeys->recv_zstream->zfree = Z_NULL; 348 349 if (inflateInit(ses.newkeys->recv_zstream) != Z_OK) { 350 dropbear_exit("zlib error"); 351 } 352 } else { 353 ses.newkeys->recv_zstream = NULL; 354 } 355 356 if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB) { 357 ses.newkeys->trans_zstream = (z_streamp)m_malloc(sizeof(z_stream)); 358 ses.newkeys->trans_zstream->zalloc = Z_NULL; 359 ses.newkeys->trans_zstream->zfree = Z_NULL; 360 361 if (deflateInit(ses.newkeys->trans_zstream, Z_DEFAULT_COMPRESSION) 362 != Z_OK) { 363 dropbear_exit("zlib error"); 364 } 365 } else { 366 ses.newkeys->trans_zstream = NULL; 367 } 368 369 /* clean up old keys */ 370 if (ses.keys->recv_zstream != NULL) { 371 if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) { 372 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ 373 dropbear_exit("crypto error"); 374 } 375 m_free(ses.keys->recv_zstream); 376 } 377 if (ses.keys->trans_zstream != NULL) { 378 if (deflateEnd(ses.keys->trans_zstream) == Z_STREAM_ERROR) { 379 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ 380 dropbear_exit("crypto error"); 381 } 382 m_free(ses.keys->trans_zstream); 383 } 384 } 385 #endif 386 387 388 /* Executed upon receiving a kexinit message from the client to initiate 389 * key exchange. If we haven't already done so, we send the list of our 390 * preferred algorithms. The client's requested algorithms are processed, 391 * and we calculate the first portion of the key-exchange-hash for used 392 * later in the key exchange. No response is sent, as the client should 393 * initiate the diffie-hellman key exchange */ 394 395 /* Originally from kex.c, generalized for cli/svr mode --mihnea */ 396 /* Belongs in common_kex.c where it should be moved after review */ 397 void recv_msg_kexinit() { 398 399 unsigned int kexhashbuf_len = 0; 400 unsigned int remote_ident_len = 0; 401 unsigned int local_ident_len = 0; 402 403 TRACE(("<- KEXINIT")) 404 TRACE(("enter recv_msg_kexinit")) 405 406 if (!ses.kexstate.sentkexinit) { 407 /* we need to send a kex packet */ 408 send_msg_kexinit(); 409 TRACE(("continue recv_msg_kexinit: sent kexinit")) 410 } 411 412 /* start the kex hash */ 413 local_ident_len = strlen(LOCAL_IDENT); 414 remote_ident_len = strlen((char*)ses.remoteident); 415 416 kexhashbuf_len = local_ident_len + remote_ident_len 417 + ses.transkexinit->len + ses.payload->len 418 + KEXHASHBUF_MAX_INTS; 419 420 ses.kexhashbuf = buf_new(kexhashbuf_len); 421 422 if (IS_DROPBEAR_CLIENT) { 423 424 /* read the peer's choice of algos */ 425 read_kex_algos(); 426 427 /* V_C, the client's version string (CR and NL excluded) */ 428 buf_putstring(ses.kexhashbuf, 429 (unsigned char*)LOCAL_IDENT, local_ident_len); 430 /* V_S, the server's version string (CR and NL excluded) */ 431 buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); 432 433 /* I_C, the payload of the client's SSH_MSG_KEXINIT */ 434 buf_putstring(ses.kexhashbuf, 435 ses.transkexinit->data, ses.transkexinit->len); 436 /* I_S, the payload of the server's SSH_MSG_KEXINIT */ 437 buf_setpos(ses.payload, 0); 438 buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len); 439 440 } else { 441 /* SERVER */ 442 443 /* read the peer's choice of algos */ 444 read_kex_algos(); 445 /* V_C, the client's version string (CR and NL excluded) */ 446 buf_putstring(ses.kexhashbuf, ses.remoteident, remote_ident_len); 447 /* V_S, the server's version string (CR and NL excluded) */ 448 buf_putstring(ses.kexhashbuf, 449 (unsigned char*)LOCAL_IDENT, local_ident_len); 450 451 /* I_C, the payload of the client's SSH_MSG_KEXINIT */ 452 buf_setpos(ses.payload, 0); 453 buf_putstring(ses.kexhashbuf, ses.payload->data, ses.payload->len); 454 455 /* I_S, the payload of the server's SSH_MSG_KEXINIT */ 456 buf_putstring(ses.kexhashbuf, 457 ses.transkexinit->data, ses.transkexinit->len); 458 459 ses.requirenext = SSH_MSG_KEXDH_INIT; 460 } 461 462 buf_free(ses.transkexinit); 463 ses.transkexinit = NULL; 464 /* the rest of ses.kexhashbuf will be done after DH exchange */ 465 466 ses.kexstate.recvkexinit = 1; 467 468 TRACE(("leave recv_msg_kexinit")) 469 } 470 471 /* Initialises and generate one side of the diffie-hellman key exchange values. 472 * See the ietf-secsh-transport draft, section 6, for details */ 473 /* dh_pub and dh_priv MUST be already initialised */ 474 void gen_kexdh_vals(mp_int *dh_pub, mp_int *dh_priv) { 475 476 DEF_MP_INT(dh_p); 477 DEF_MP_INT(dh_q); 478 DEF_MP_INT(dh_g); 479 480 TRACE(("enter send_msg_kexdh_reply")) 481 482 m_mp_init_multi(&dh_g, &dh_p, &dh_q, NULL); 483 484 /* read the prime and generator*/ 485 bytes_to_mp(&dh_p, (unsigned char*)dh_p_val, DH_P_LEN); 486 487 if (mp_set_int(&dh_g, DH_G_VAL) != MP_OKAY) { 488 dropbear_exit("Diffie-Hellman error"); 489 } 490 491 /* calculate q = (p-1)/2 */ 492 /* dh_priv is just a temp var here */ 493 if (mp_sub_d(&dh_p, 1, dh_priv) != MP_OKAY) { 494 dropbear_exit("Diffie-Hellman error"); 495 } 496 if (mp_div_2(dh_priv, &dh_q) != MP_OKAY) { 497 dropbear_exit("Diffie-Hellman error"); 498 } 499 500 /* Generate a private portion 0 < dh_priv < dh_q */ 501 gen_random_mpint(&dh_q, dh_priv); 502 503 /* f = g^y mod p */ 504 if (mp_exptmod(&dh_g, dh_priv, &dh_p, dh_pub) != MP_OKAY) { 505 dropbear_exit("Diffie-Hellman error"); 506 } 507 mp_clear_multi(&dh_g, &dh_p, &dh_q, NULL); 508 } 509 510 /* This function is fairly common between client/server, with some substitution 511 * of dh_e/dh_f etc. Hence these arguments: 512 * dh_pub_us is 'e' for the client, 'f' for the server. dh_pub_them is 513 * vice-versa. dh_priv is the x/y value corresponding to dh_pub_us */ 514 void kexdh_comb_key(mp_int *dh_pub_us, mp_int *dh_priv, mp_int *dh_pub_them, 515 sign_key *hostkey) { 516 517 mp_int dh_p; 518 mp_int *dh_e = NULL, *dh_f = NULL; 519 hash_state hs; 520 521 /* read the prime and generator*/ 522 m_mp_init(&dh_p); 523 bytes_to_mp(&dh_p, dh_p_val, DH_P_LEN); 524 525 /* Check that dh_pub_them (dh_e or dh_f) is in the range [1, p-1] */ 526 if (mp_cmp(dh_pub_them, &dh_p) != MP_LT 527 || mp_cmp_d(dh_pub_them, 0) != MP_GT) { 528 dropbear_exit("Diffie-Hellman error"); 529 } 530 531 /* K = e^y mod p = f^x mod p */ 532 ses.dh_K = (mp_int*)m_malloc(sizeof(mp_int)); 533 m_mp_init(ses.dh_K); 534 if (mp_exptmod(dh_pub_them, dh_priv, &dh_p, ses.dh_K) != MP_OKAY) { 535 dropbear_exit("Diffie-Hellman error"); 536 } 537 538 /* clear no longer needed vars */ 539 mp_clear_multi(&dh_p, NULL); 540 541 /* From here on, the code needs to work with the _same_ vars on each side, 542 * not vice-versaing for client/server */ 543 if (IS_DROPBEAR_CLIENT) { 544 dh_e = dh_pub_us; 545 dh_f = dh_pub_them; 546 } else { 547 dh_e = dh_pub_them; 548 dh_f = dh_pub_us; 549 } 550 551 /* Create the remainder of the hash buffer, to generate the exchange hash */ 552 /* K_S, the host key */ 553 buf_put_pub_key(ses.kexhashbuf, hostkey, ses.newkeys->algo_hostkey); 554 /* e, exchange value sent by the client */ 555 buf_putmpint(ses.kexhashbuf, dh_e); 556 /* f, exchange value sent by the server */ 557 buf_putmpint(ses.kexhashbuf, dh_f); 558 /* K, the shared secret */ 559 buf_putmpint(ses.kexhashbuf, ses.dh_K); 560 561 /* calculate the hash H to sign */ 562 sha1_init(&hs); 563 buf_setpos(ses.kexhashbuf, 0); 564 sha1_process(&hs, buf_getptr(ses.kexhashbuf, ses.kexhashbuf->len), 565 ses.kexhashbuf->len); 566 sha1_done(&hs, ses.hash); 567 568 buf_burn(ses.kexhashbuf); 569 buf_free(ses.kexhashbuf); 570 ses.kexhashbuf = NULL; 571 572 /* first time around, we set the session_id to H */ 573 if (ses.session_id == NULL) { 574 /* create the session_id, this never needs freeing */ 575 ses.session_id = (unsigned char*)m_malloc(SHA1_HASH_SIZE); 576 memcpy(ses.session_id, ses.hash, SHA1_HASH_SIZE); 577 } 578 } 579 580 /* read the other side's algo list. buf_match_algo is a callback to match 581 * algos for the client or server. */ 582 static void read_kex_algos() { 583 584 /* for asymmetry */ 585 algo_type * c2s_hash_algo = NULL; 586 algo_type * s2c_hash_algo = NULL; 587 algo_type * c2s_cipher_algo = NULL; 588 algo_type * s2c_cipher_algo = NULL; 589 algo_type * c2s_comp_algo = NULL; 590 algo_type * s2c_comp_algo = NULL; 591 /* the generic one */ 592 algo_type * algo = NULL; 593 594 /* which algo couldn't match */ 595 char * erralgo = NULL; 596 597 int goodguess = 0; 598 int allgood = 1; /* we AND this with each goodguess and see if its still 599 true after */ 600 601 buf_incrpos(ses.payload, 16); /* start after the cookie */ 602 603 ses.newkeys = (struct key_context*)m_malloc(sizeof(struct key_context)); 604 605 /* kex_algorithms */ 606 algo = ses.buf_match_algo(ses.payload, sshkex, &goodguess); 607 allgood &= goodguess; 608 if (algo == NULL) { 609 erralgo = "kex"; 610 goto error; 611 } 612 TRACE(("kex algo %s", algo->name)) 613 ses.newkeys->algo_kex = algo->val; 614 615 /* server_host_key_algorithms */ 616 algo = ses.buf_match_algo(ses.payload, sshhostkey, &goodguess); 617 allgood &= goodguess; 618 if (algo == NULL) { 619 erralgo = "hostkey"; 620 goto error; 621 } 622 TRACE(("hostkey algo %s", algo->name)) 623 ses.newkeys->algo_hostkey = algo->val; 624 625 /* encryption_algorithms_client_to_server */ 626 c2s_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); 627 if (c2s_cipher_algo == NULL) { 628 erralgo = "enc c->s"; 629 goto error; 630 } 631 TRACE(("enc c2s is %s", c2s_cipher_algo->name)) 632 633 /* encryption_algorithms_server_to_client */ 634 s2c_cipher_algo = ses.buf_match_algo(ses.payload, sshciphers, &goodguess); 635 if (s2c_cipher_algo == NULL) { 636 erralgo = "enc s->c"; 637 goto error; 638 } 639 TRACE(("enc s2c is %s", s2c_cipher_algo->name)) 640 641 /* mac_algorithms_client_to_server */ 642 c2s_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); 643 if (c2s_hash_algo == NULL) { 644 erralgo = "mac c->s"; 645 goto error; 646 } 647 TRACE(("hash c2s is %s", c2s_hash_algo->name)) 648 649 /* mac_algorithms_server_to_client */ 650 s2c_hash_algo = ses.buf_match_algo(ses.payload, sshhashes, &goodguess); 651 if (s2c_hash_algo == NULL) { 652 erralgo = "mac s->c"; 653 goto error; 654 } 655 TRACE(("hash s2c is %s", s2c_hash_algo->name)) 656 657 /* compression_algorithms_client_to_server */ 658 c2s_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); 659 if (c2s_comp_algo == NULL) { 660 erralgo = "comp c->s"; 661 goto error; 662 } 663 TRACE(("hash c2s is %s", c2s_comp_algo->name)) 664 665 /* compression_algorithms_server_to_client */ 666 s2c_comp_algo = ses.buf_match_algo(ses.payload, sshcompress, &goodguess); 667 if (s2c_comp_algo == NULL) { 668 erralgo = "comp s->c"; 669 goto error; 670 } 671 TRACE(("hash s2c is %s", s2c_comp_algo->name)) 672 673 /* languages_client_to_server */ 674 buf_eatstring(ses.payload); 675 676 /* languages_server_to_client */ 677 buf_eatstring(ses.payload); 678 679 /* first_kex_packet_follows */ 680 if (buf_getbool(ses.payload)) { 681 ses.kexstate.firstfollows = 1; 682 /* if the guess wasn't good, we ignore the packet sent */ 683 if (!allgood) { 684 ses.ignorenext = 1; 685 } 686 } 687 688 /* Handle the asymmetry */ 689 if (IS_DROPBEAR_CLIENT) { 690 ses.newkeys->recv_algo_crypt = 691 (struct dropbear_cipher*)s2c_cipher_algo->data; 692 ses.newkeys->trans_algo_crypt = 693 (struct dropbear_cipher*)c2s_cipher_algo->data; 694 ses.newkeys->recv_algo_mac = 695 (struct dropbear_hash*)s2c_hash_algo->data; 696 ses.newkeys->trans_algo_mac = 697 (struct dropbear_hash*)c2s_hash_algo->data; 698 ses.newkeys->recv_algo_comp = s2c_comp_algo->val; 699 ses.newkeys->trans_algo_comp = c2s_comp_algo->val; 700 } else { 701 /* SERVER */ 702 ses.newkeys->recv_algo_crypt = 703 (struct dropbear_cipher*)c2s_cipher_algo->data; 704 ses.newkeys->trans_algo_crypt = 705 (struct dropbear_cipher*)s2c_cipher_algo->data; 706 ses.newkeys->recv_algo_mac = 707 (struct dropbear_hash*)c2s_hash_algo->data; 708 ses.newkeys->trans_algo_mac = 709 (struct dropbear_hash*)s2c_hash_algo->data; 710 ses.newkeys->recv_algo_comp = c2s_comp_algo->val; 711 ses.newkeys->trans_algo_comp = s2c_comp_algo->val; 712 } 713 714 /* reserved for future extensions */ 715 buf_getint(ses.payload); 716 return; 717 718 error: 719 dropbear_exit("no matching algo %s", erralgo); 720 } 721