comparison common-kex.c @ 534:0431915df79f

- Get rid of decryptreadbuf, just decrypt in-place with readbuf - Share make_mac function for both packet creation and validation - Split recv/trans parts of key_context into their own structures
author Matt Johnston <matt@ucc.asn.au>
date Sun, 01 Mar 2009 16:15:57 +0000
parents 43bbe17d6ba0
children daf52f813328
comparison
equal deleted inserted replaced
533:805ae74ec024 534:0431915df79f
270 if (IS_DROPBEAR_CLIENT) { 270 if (IS_DROPBEAR_CLIENT) {
271 trans_IV = C2S_IV; 271 trans_IV = C2S_IV;
272 recv_IV = S2C_IV; 272 recv_IV = S2C_IV;
273 trans_key = C2S_key; 273 trans_key = C2S_key;
274 recv_key = S2C_key; 274 recv_key = S2C_key;
275 C2S_keysize = ses.newkeys->trans_algo_crypt->keysize; 275 C2S_keysize = ses.newkeys->trans.algo_crypt->keysize;
276 S2C_keysize = ses.newkeys->recv_algo_crypt->keysize; 276 S2C_keysize = ses.newkeys->recv.algo_crypt->keysize;
277 mactransletter = 'E'; 277 mactransletter = 'E';
278 macrecvletter = 'F'; 278 macrecvletter = 'F';
279 } else { 279 } else {
280 trans_IV = S2C_IV; 280 trans_IV = S2C_IV;
281 recv_IV = C2S_IV; 281 recv_IV = C2S_IV;
282 trans_key = S2C_key; 282 trans_key = S2C_key;
283 recv_key = C2S_key; 283 recv_key = C2S_key;
284 C2S_keysize = ses.newkeys->recv_algo_crypt->keysize; 284 C2S_keysize = ses.newkeys->recv.algo_crypt->keysize;
285 S2C_keysize = ses.newkeys->trans_algo_crypt->keysize; 285 S2C_keysize = ses.newkeys->trans.algo_crypt->keysize;
286 mactransletter = 'F'; 286 mactransletter = 'F';
287 macrecvletter = 'E'; 287 macrecvletter = 'E';
288 } 288 }
289 289
290 hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A'); 290 hashkeys(C2S_IV, SHA1_HASH_SIZE, &hs, 'A');
291 hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B'); 291 hashkeys(S2C_IV, SHA1_HASH_SIZE, &hs, 'B');
292 hashkeys(C2S_key, C2S_keysize, &hs, 'C'); 292 hashkeys(C2S_key, C2S_keysize, &hs, 'C');
293 hashkeys(S2C_key, S2C_keysize, &hs, 'D'); 293 hashkeys(S2C_key, S2C_keysize, &hs, 'D');
294 294
295 recv_cipher = find_cipher(ses.newkeys->recv_algo_crypt->cipherdesc->name); 295 recv_cipher = find_cipher(ses.newkeys->recv.algo_crypt->cipherdesc->name);
296 if (recv_cipher < 0) 296 if (recv_cipher < 0)
297 dropbear_exit("crypto error"); 297 dropbear_exit("crypto error");
298 if (ses.newkeys->recv_crypt_mode->start(recv_cipher, 298 if (ses.newkeys->recv.crypt_mode->start(recv_cipher,
299 recv_IV, recv_key, 299 recv_IV, recv_key,
300 ses.newkeys->recv_algo_crypt->keysize, 0, 300 ses.newkeys->recv.algo_crypt->keysize, 0,
301 &ses.newkeys->recv_cipher_state) != CRYPT_OK) { 301 &ses.newkeys->recv.cipher_state) != CRYPT_OK) {
302 dropbear_exit("crypto error"); 302 dropbear_exit("crypto error");
303 } 303 }
304 304
305 trans_cipher = find_cipher(ses.newkeys->trans_algo_crypt->cipherdesc->name); 305 trans_cipher = find_cipher(ses.newkeys->trans.algo_crypt->cipherdesc->name);
306 if (trans_cipher < 0) 306 if (trans_cipher < 0)
307 dropbear_exit("crypto error"); 307 dropbear_exit("crypto error");
308 if (ses.newkeys->trans_crypt_mode->start(trans_cipher, 308 if (ses.newkeys->trans.crypt_mode->start(trans_cipher,
309 trans_IV, trans_key, 309 trans_IV, trans_key,
310 ses.newkeys->trans_algo_crypt->keysize, 0, 310 ses.newkeys->trans.algo_crypt->keysize, 0,
311 &ses.newkeys->trans_cipher_state) != CRYPT_OK) { 311 &ses.newkeys->trans.cipher_state) != CRYPT_OK) {
312 dropbear_exit("crypto error"); 312 dropbear_exit("crypto error");
313 } 313 }
314 314
315 /* MAC keys */ 315 /* MAC keys */
316 hashkeys(ses.newkeys->transmackey, 316 hashkeys(ses.newkeys->trans.mackey,
317 ses.newkeys->trans_algo_mac->keysize, &hs, mactransletter); 317 ses.newkeys->trans.algo_mac->keysize, &hs, mactransletter);
318 hashkeys(ses.newkeys->recvmackey, 318 hashkeys(ses.newkeys->recv.mackey,
319 ses.newkeys->recv_algo_mac->keysize, &hs, macrecvletter); 319 ses.newkeys->recv.algo_mac->keysize, &hs, macrecvletter);
320 ses.newkeys->trans.hash_index = find_hash(ses.newkeys->trans.algo_mac->hashdesc->name),
321 ses.newkeys->recv.hash_index = find_hash(ses.newkeys->recv.algo_mac->hashdesc->name),
320 322
321 #ifndef DISABLE_ZLIB 323 #ifndef DISABLE_ZLIB
322 gen_new_zstreams(); 324 gen_new_zstreams();
323 #endif 325 #endif
324 326
332 } 334 }
333 335
334 #ifndef DISABLE_ZLIB 336 #ifndef DISABLE_ZLIB
335 337
336 int is_compress_trans() { 338 int is_compress_trans() {
337 return ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB 339 return ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB
338 || (ses.authstate.authdone 340 || (ses.authstate.authdone
339 && ses.keys->trans_algo_comp == DROPBEAR_COMP_ZLIB_DELAY); 341 && ses.keys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
340 } 342 }
341 343
342 int is_compress_recv() { 344 int is_compress_recv() {
343 return ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB 345 return ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB
344 || (ses.authstate.authdone 346 || (ses.authstate.authdone
345 && ses.keys->recv_algo_comp == DROPBEAR_COMP_ZLIB_DELAY); 347 && ses.keys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY);
346 } 348 }
347 349
348 /* Set up new zlib compression streams, close the old ones. Only 350 /* Set up new zlib compression streams, close the old ones. Only
349 * called from gen_new_keys() */ 351 * called from gen_new_keys() */
350 static void gen_new_zstreams() { 352 static void gen_new_zstreams() {
351 353
352 /* create new zstreams */ 354 /* create new zstreams */
353 if (ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB 355 if (ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB
354 || ses.newkeys->recv_algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { 356 || ses.newkeys->recv.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) {
355 ses.newkeys->recv_zstream = (z_streamp)m_malloc(sizeof(z_stream)); 357 ses.newkeys->recv.zstream = (z_streamp)m_malloc(sizeof(z_stream));
356 ses.newkeys->recv_zstream->zalloc = Z_NULL; 358 ses.newkeys->recv.zstream->zalloc = Z_NULL;
357 ses.newkeys->recv_zstream->zfree = Z_NULL; 359 ses.newkeys->recv.zstream->zfree = Z_NULL;
358 360
359 if (inflateInit(ses.newkeys->recv_zstream) != Z_OK) { 361 if (inflateInit(ses.newkeys->recv.zstream) != Z_OK) {
360 dropbear_exit("zlib error"); 362 dropbear_exit("zlib error");
361 } 363 }
362 } else { 364 } else {
363 ses.newkeys->recv_zstream = NULL; 365 ses.newkeys->recv.zstream = NULL;
364 } 366 }
365 367
366 if (ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB 368 if (ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB
367 || ses.newkeys->trans_algo_comp == DROPBEAR_COMP_ZLIB_DELAY) { 369 || ses.newkeys->trans.algo_comp == DROPBEAR_COMP_ZLIB_DELAY) {
368 ses.newkeys->trans_zstream = (z_streamp)m_malloc(sizeof(z_stream)); 370 ses.newkeys->trans.zstream = (z_streamp)m_malloc(sizeof(z_stream));
369 ses.newkeys->trans_zstream->zalloc = Z_NULL; 371 ses.newkeys->trans.zstream->zalloc = Z_NULL;
370 ses.newkeys->trans_zstream->zfree = Z_NULL; 372 ses.newkeys->trans.zstream->zfree = Z_NULL;
371 373
372 if (deflateInit(ses.newkeys->trans_zstream, Z_DEFAULT_COMPRESSION) 374 if (deflateInit(ses.newkeys->trans.zstream, Z_DEFAULT_COMPRESSION)
373 != Z_OK) { 375 != Z_OK) {
374 dropbear_exit("zlib error"); 376 dropbear_exit("zlib error");
375 } 377 }
376 } else { 378 } else {
377 ses.newkeys->trans_zstream = NULL; 379 ses.newkeys->trans.zstream = NULL;
378 } 380 }
379 381
380 /* clean up old keys */ 382 /* clean up old keys */
381 if (ses.keys->recv_zstream != NULL) { 383 if (ses.keys->recv.zstream != NULL) {
382 if (inflateEnd(ses.keys->recv_zstream) == Z_STREAM_ERROR) { 384 if (inflateEnd(ses.keys->recv.zstream) == Z_STREAM_ERROR) {
383 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ 385 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
384 dropbear_exit("crypto error"); 386 dropbear_exit("crypto error");
385 } 387 }
386 m_free(ses.keys->recv_zstream); 388 m_free(ses.keys->recv.zstream);
387 } 389 }
388 if (ses.keys->trans_zstream != NULL) { 390 if (ses.keys->trans.zstream != NULL) {
389 if (deflateEnd(ses.keys->trans_zstream) == Z_STREAM_ERROR) { 391 if (deflateEnd(ses.keys->trans.zstream) == Z_STREAM_ERROR) {
390 /* Z_DATA_ERROR is ok, just means that stream isn't ended */ 392 /* Z_DATA_ERROR is ok, just means that stream isn't ended */
391 dropbear_exit("crypto error"); 393 dropbear_exit("crypto error");
392 } 394 }
393 m_free(ses.keys->trans_zstream); 395 m_free(ses.keys->trans.zstream);
394 } 396 }
395 } 397 }
396 #endif /* DISABLE_ZLIB */ 398 #endif /* DISABLE_ZLIB */
397 399
398 400
696 } 698 }
697 } 699 }
698 700
699 /* Handle the asymmetry */ 701 /* Handle the asymmetry */
700 if (IS_DROPBEAR_CLIENT) { 702 if (IS_DROPBEAR_CLIENT) {
701 ses.newkeys->recv_algo_crypt = 703 ses.newkeys->recv.algo_crypt =
702 (struct dropbear_cipher*)s2c_cipher_algo->data; 704 (struct dropbear_cipher*)s2c_cipher_algo->data;
703 ses.newkeys->trans_algo_crypt = 705 ses.newkeys->trans.algo_crypt =
704 (struct dropbear_cipher*)c2s_cipher_algo->data; 706 (struct dropbear_cipher*)c2s_cipher_algo->data;
705 ses.newkeys->recv_crypt_mode = 707 ses.newkeys->recv.crypt_mode =
706 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; 708 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
707 ses.newkeys->trans_crypt_mode = 709 ses.newkeys->trans.crypt_mode =
708 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; 710 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
709 ses.newkeys->recv_algo_mac = 711 ses.newkeys->recv.algo_mac =
710 (struct dropbear_hash*)s2c_hash_algo->data; 712 (struct dropbear_hash*)s2c_hash_algo->data;
711 ses.newkeys->trans_algo_mac = 713 ses.newkeys->trans.algo_mac =
712 (struct dropbear_hash*)c2s_hash_algo->data; 714 (struct dropbear_hash*)c2s_hash_algo->data;
713 ses.newkeys->recv_algo_comp = s2c_comp_algo->val; 715 ses.newkeys->recv.algo_comp = s2c_comp_algo->val;
714 ses.newkeys->trans_algo_comp = c2s_comp_algo->val; 716 ses.newkeys->trans.algo_comp = c2s_comp_algo->val;
715 } else { 717 } else {
716 /* SERVER */ 718 /* SERVER */
717 ses.newkeys->recv_algo_crypt = 719 ses.newkeys->recv.algo_crypt =
718 (struct dropbear_cipher*)c2s_cipher_algo->data; 720 (struct dropbear_cipher*)c2s_cipher_algo->data;
719 ses.newkeys->trans_algo_crypt = 721 ses.newkeys->trans.algo_crypt =
720 (struct dropbear_cipher*)s2c_cipher_algo->data; 722 (struct dropbear_cipher*)s2c_cipher_algo->data;
721 ses.newkeys->recv_crypt_mode = 723 ses.newkeys->recv.crypt_mode =
722 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode; 724 (struct dropbear_cipher_mode*)c2s_cipher_algo->mode;
723 ses.newkeys->trans_crypt_mode = 725 ses.newkeys->trans.crypt_mode =
724 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode; 726 (struct dropbear_cipher_mode*)s2c_cipher_algo->mode;
725 ses.newkeys->recv_algo_mac = 727 ses.newkeys->recv.algo_mac =
726 (struct dropbear_hash*)c2s_hash_algo->data; 728 (struct dropbear_hash*)c2s_hash_algo->data;
727 ses.newkeys->trans_algo_mac = 729 ses.newkeys->trans.algo_mac =
728 (struct dropbear_hash*)s2c_hash_algo->data; 730 (struct dropbear_hash*)s2c_hash_algo->data;
729 ses.newkeys->recv_algo_comp = c2s_comp_algo->val; 731 ses.newkeys->recv.algo_comp = c2s_comp_algo->val;
730 ses.newkeys->trans_algo_comp = s2c_comp_algo->val; 732 ses.newkeys->trans.algo_comp = s2c_comp_algo->val;
731 } 733 }
732 734
733 /* reserved for future extensions */ 735 /* reserved for future extensions */
734 buf_getint(ses.payload); 736 buf_getint(ses.payload);
735 return; 737 return;