diff options
-rw-r--r-- | cipher-chachapoly.c | 5 | ||||
-rw-r--r-- | cipher.c | 165 | ||||
-rw-r--r-- | cipher.h | 23 | ||||
-rw-r--r-- | packet.c | 88 | ||||
-rw-r--r-- | sshkey.c | 37 |
5 files changed, 179 insertions, 139 deletions
diff --git a/cipher-chachapoly.c b/cipher-chachapoly.c index 7f31ff4ce..0899c5ad5 100644 --- a/cipher-chachapoly.c +++ b/cipher-chachapoly.c | |||
@@ -14,7 +14,7 @@ | |||
14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | 14 | * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | /* $OpenBSD: cipher-chachapoly.c,v 1.7 2015/01/14 10:24:42 markus Exp $ */ | 17 | /* $OpenBSD: cipher-chachapoly.c,v 1.8 2016/08/03 05:41:57 djm Exp $ */ |
18 | 18 | ||
19 | #include "includes.h" | 19 | #include "includes.h" |
20 | 20 | ||
@@ -28,7 +28,8 @@ | |||
28 | #include "ssherr.h" | 28 | #include "ssherr.h" |
29 | #include "cipher-chachapoly.h" | 29 | #include "cipher-chachapoly.h" |
30 | 30 | ||
31 | int chachapoly_init(struct chachapoly_ctx *ctx, | 31 | int |
32 | chachapoly_init(struct chachapoly_ctx *ctx, | ||
32 | const u_char *key, u_int keylen) | 33 | const u_char *key, u_int keylen) |
33 | { | 34 | { |
34 | if (keylen != (32 + 32)) /* 2 x 256 bit keys */ | 35 | if (keylen != (32 + 32)) /* 2 x 256 bit keys */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.c,v 1.101 2015/12/10 17:08:40 mmcc Exp $ */ | 1 | /* $OpenBSD: cipher.c,v 1.102 2016/08/03 05:41:57 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -57,6 +57,15 @@ extern const EVP_CIPHER *evp_ssh1_3des(void); | |||
57 | extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); | 57 | extern int ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); |
58 | #endif | 58 | #endif |
59 | 59 | ||
60 | struct sshcipher_ctx { | ||
61 | int plaintext; | ||
62 | int encrypt; | ||
63 | EVP_CIPHER_CTX *evp; | ||
64 | struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ | ||
65 | struct aesctr_ctx ac_ctx; /* XXX union with evp? */ | ||
66 | const struct sshcipher *cipher; | ||
67 | }; | ||
68 | |||
60 | struct sshcipher { | 69 | struct sshcipher { |
61 | char *name; | 70 | char *name; |
62 | int number; /* for ssh1 only */ | 71 | int number; /* for ssh1 only */ |
@@ -206,6 +215,18 @@ cipher_is_cbc(const struct sshcipher *c) | |||
206 | } | 215 | } |
207 | 216 | ||
208 | u_int | 217 | u_int |
218 | cipher_ctx_is_plaintext(struct sshcipher_ctx *cc) | ||
219 | { | ||
220 | return cc->plaintext; | ||
221 | } | ||
222 | |||
223 | u_int | ||
224 | cipher_ctx_get_number(struct sshcipher_ctx *cc) | ||
225 | { | ||
226 | return cc->cipher->number; | ||
227 | } | ||
228 | |||
229 | u_int | ||
209 | cipher_mask_ssh1(int client) | 230 | cipher_mask_ssh1(int client) |
210 | { | 231 | { |
211 | u_int mask = 0; | 232 | u_int mask = 0; |
@@ -297,65 +318,81 @@ cipher_warning_message(const struct sshcipher_ctx *cc) | |||
297 | } | 318 | } |
298 | 319 | ||
299 | int | 320 | int |
300 | cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher, | 321 | cipher_init(struct sshcipher_ctx **ccp, const struct sshcipher *cipher, |
301 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, | 322 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, |
302 | int do_encrypt) | 323 | int do_encrypt) |
303 | { | 324 | { |
304 | #ifdef WITH_OPENSSL | 325 | struct sshcipher_ctx *cc = NULL; |
305 | int ret = SSH_ERR_INTERNAL_ERROR; | 326 | int ret = SSH_ERR_INTERNAL_ERROR; |
327 | #ifdef WITH_OPENSSL | ||
306 | const EVP_CIPHER *type; | 328 | const EVP_CIPHER *type; |
307 | int klen; | 329 | int klen; |
308 | u_char *junk, *discard; | 330 | u_char *junk, *discard; |
331 | #endif | ||
332 | |||
333 | *ccp = NULL; | ||
334 | if ((cc = calloc(sizeof(*cc), 1)) == NULL) | ||
335 | return SSH_ERR_ALLOC_FAIL; | ||
309 | 336 | ||
310 | if (cipher->number == SSH_CIPHER_DES) { | 337 | if (cipher->number == SSH_CIPHER_DES) { |
311 | if (keylen > 8) | 338 | if (keylen > 8) |
312 | keylen = 8; | 339 | keylen = 8; |
313 | } | 340 | } |
314 | #endif | 341 | |
315 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); | 342 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); |
316 | cc->encrypt = do_encrypt; | 343 | cc->encrypt = do_encrypt; |
317 | 344 | ||
318 | if (keylen < cipher->key_len || | 345 | if (keylen < cipher->key_len || |
319 | (iv != NULL && ivlen < cipher_ivlen(cipher))) | 346 | (iv != NULL && ivlen < cipher_ivlen(cipher))) { |
320 | return SSH_ERR_INVALID_ARGUMENT; | 347 | ret = SSH_ERR_INVALID_ARGUMENT; |
348 | goto out; | ||
349 | } | ||
321 | 350 | ||
322 | cc->cipher = cipher; | 351 | cc->cipher = cipher; |
323 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { | 352 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { |
324 | return chachapoly_init(&cc->cp_ctx, key, keylen); | 353 | ret = chachapoly_init(&cc->cp_ctx, key, keylen); |
354 | goto out; | ||
325 | } | 355 | } |
326 | #ifndef WITH_OPENSSL | 356 | #ifndef WITH_OPENSSL |
327 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | 357 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { |
328 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); | 358 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); |
329 | aesctr_ivsetup(&cc->ac_ctx, iv); | 359 | aesctr_ivsetup(&cc->ac_ctx, iv); |
330 | return 0; | 360 | ret = 0; |
361 | goto out; | ||
331 | } | 362 | } |
332 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | 363 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { |
333 | return 0; | 364 | ret = 0; |
334 | return SSH_ERR_INVALID_ARGUMENT; | 365 | goto out; |
335 | #else | 366 | } |
367 | ret = SSH_ERR_INVALID_ARGUMENT; | ||
368 | goto out; | ||
369 | #else /* WITH_OPENSSL */ | ||
336 | type = (*cipher->evptype)(); | 370 | type = (*cipher->evptype)(); |
337 | EVP_CIPHER_CTX_init(&cc->evp); | 371 | if ((cc->evp = EVP_CIPHER_CTX_new()) == NULL) { |
338 | if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv, | 372 | ret = SSH_ERR_ALLOC_FAIL; |
373 | goto out; | ||
374 | } | ||
375 | if (EVP_CipherInit(cc->evp, type, NULL, (u_char *)iv, | ||
339 | (do_encrypt == CIPHER_ENCRYPT)) == 0) { | 376 | (do_encrypt == CIPHER_ENCRYPT)) == 0) { |
340 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 377 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
341 | goto bad; | 378 | goto out; |
342 | } | 379 | } |
343 | if (cipher_authlen(cipher) && | 380 | if (cipher_authlen(cipher) && |
344 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, | 381 | !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_IV_FIXED, |
345 | -1, (u_char *)iv)) { | 382 | -1, (u_char *)iv)) { |
346 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 383 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
347 | goto bad; | 384 | goto out; |
348 | } | 385 | } |
349 | klen = EVP_CIPHER_CTX_key_length(&cc->evp); | 386 | klen = EVP_CIPHER_CTX_key_length(cc->evp); |
350 | if (klen > 0 && keylen != (u_int)klen) { | 387 | if (klen > 0 && keylen != (u_int)klen) { |
351 | if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0) { | 388 | if (EVP_CIPHER_CTX_set_key_length(cc->evp, keylen) == 0) { |
352 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 389 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
353 | goto bad; | 390 | goto out; |
354 | } | 391 | } |
355 | } | 392 | } |
356 | if (EVP_CipherInit(&cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { | 393 | if (EVP_CipherInit(cc->evp, NULL, (u_char *)key, NULL, -1) == 0) { |
357 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 394 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
358 | goto bad; | 395 | goto out; |
359 | } | 396 | } |
360 | 397 | ||
361 | if (cipher->discard_len > 0) { | 398 | if (cipher->discard_len > 0) { |
@@ -363,21 +400,34 @@ cipher_init(struct sshcipher_ctx *cc, const struct sshcipher *cipher, | |||
363 | (discard = malloc(cipher->discard_len)) == NULL) { | 400 | (discard = malloc(cipher->discard_len)) == NULL) { |
364 | free(junk); | 401 | free(junk); |
365 | ret = SSH_ERR_ALLOC_FAIL; | 402 | ret = SSH_ERR_ALLOC_FAIL; |
366 | goto bad; | 403 | goto out; |
367 | } | 404 | } |
368 | ret = EVP_Cipher(&cc->evp, discard, junk, cipher->discard_len); | 405 | ret = EVP_Cipher(cc->evp, discard, junk, cipher->discard_len); |
369 | explicit_bzero(discard, cipher->discard_len); | 406 | explicit_bzero(discard, cipher->discard_len); |
370 | free(junk); | 407 | free(junk); |
371 | free(discard); | 408 | free(discard); |
372 | if (ret != 1) { | 409 | if (ret != 1) { |
373 | ret = SSH_ERR_LIBCRYPTO_ERROR; | 410 | ret = SSH_ERR_LIBCRYPTO_ERROR; |
374 | bad: | 411 | goto out; |
375 | EVP_CIPHER_CTX_cleanup(&cc->evp); | ||
376 | return ret; | ||
377 | } | 412 | } |
378 | } | 413 | } |
379 | #endif | 414 | ret = 0; |
380 | return 0; | 415 | #endif /* WITH_OPENSSL */ |
416 | out: | ||
417 | if (ret == 0) { | ||
418 | /* success */ | ||
419 | *ccp = cc; | ||
420 | } else { | ||
421 | if (cc != NULL) { | ||
422 | #ifdef WITH_OPENSSL | ||
423 | if (cc->evp != NULL) | ||
424 | EVP_CIPHER_CTX_free(cc->evp); | ||
425 | #endif /* WITH_OPENSSL */ | ||
426 | explicit_bzero(cc, sizeof(*cc)); | ||
427 | free(cc); | ||
428 | } | ||
429 | } | ||
430 | return ret; | ||
381 | } | 431 | } |
382 | 432 | ||
383 | /* | 433 | /* |
@@ -418,33 +468,33 @@ cipher_crypt(struct sshcipher_ctx *cc, u_int seqnr, u_char *dest, | |||
418 | if (authlen != cipher_authlen(cc->cipher)) | 468 | if (authlen != cipher_authlen(cc->cipher)) |
419 | return SSH_ERR_INVALID_ARGUMENT; | 469 | return SSH_ERR_INVALID_ARGUMENT; |
420 | /* increment IV */ | 470 | /* increment IV */ |
421 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, | 471 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, |
422 | 1, lastiv)) | 472 | 1, lastiv)) |
423 | return SSH_ERR_LIBCRYPTO_ERROR; | 473 | return SSH_ERR_LIBCRYPTO_ERROR; |
424 | /* set tag on decyption */ | 474 | /* set tag on decyption */ |
425 | if (!cc->encrypt && | 475 | if (!cc->encrypt && |
426 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_SET_TAG, | 476 | !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_SET_TAG, |
427 | authlen, (u_char *)src + aadlen + len)) | 477 | authlen, (u_char *)src + aadlen + len)) |
428 | return SSH_ERR_LIBCRYPTO_ERROR; | 478 | return SSH_ERR_LIBCRYPTO_ERROR; |
429 | } | 479 | } |
430 | if (aadlen) { | 480 | if (aadlen) { |
431 | if (authlen && | 481 | if (authlen && |
432 | EVP_Cipher(&cc->evp, NULL, (u_char *)src, aadlen) < 0) | 482 | EVP_Cipher(cc->evp, NULL, (u_char *)src, aadlen) < 0) |
433 | return SSH_ERR_LIBCRYPTO_ERROR; | 483 | return SSH_ERR_LIBCRYPTO_ERROR; |
434 | memcpy(dest, src, aadlen); | 484 | memcpy(dest, src, aadlen); |
435 | } | 485 | } |
436 | if (len % cc->cipher->block_size) | 486 | if (len % cc->cipher->block_size) |
437 | return SSH_ERR_INVALID_ARGUMENT; | 487 | return SSH_ERR_INVALID_ARGUMENT; |
438 | if (EVP_Cipher(&cc->evp, dest + aadlen, (u_char *)src + aadlen, | 488 | if (EVP_Cipher(cc->evp, dest + aadlen, (u_char *)src + aadlen, |
439 | len) < 0) | 489 | len) < 0) |
440 | return SSH_ERR_LIBCRYPTO_ERROR; | 490 | return SSH_ERR_LIBCRYPTO_ERROR; |
441 | if (authlen) { | 491 | if (authlen) { |
442 | /* compute tag (on encrypt) or verify tag (on decrypt) */ | 492 | /* compute tag (on encrypt) or verify tag (on decrypt) */ |
443 | if (EVP_Cipher(&cc->evp, NULL, NULL, 0) < 0) | 493 | if (EVP_Cipher(cc->evp, NULL, NULL, 0) < 0) |
444 | return cc->encrypt ? | 494 | return cc->encrypt ? |
445 | SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; | 495 | SSH_ERR_LIBCRYPTO_ERROR : SSH_ERR_MAC_INVALID; |
446 | if (cc->encrypt && | 496 | if (cc->encrypt && |
447 | !EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_GET_TAG, | 497 | !EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_GET_TAG, |
448 | authlen, dest + aadlen + len)) | 498 | authlen, dest + aadlen + len)) |
449 | return SSH_ERR_LIBCRYPTO_ERROR; | 499 | return SSH_ERR_LIBCRYPTO_ERROR; |
450 | } | 500 | } |
@@ -466,20 +516,23 @@ cipher_get_length(struct sshcipher_ctx *cc, u_int *plenp, u_int seqnr, | |||
466 | return 0; | 516 | return 0; |
467 | } | 517 | } |
468 | 518 | ||
469 | int | 519 | void |
470 | cipher_cleanup(struct sshcipher_ctx *cc) | 520 | cipher_free(struct sshcipher_ctx *cc) |
471 | { | 521 | { |
472 | if (cc == NULL || cc->cipher == NULL) | 522 | if (cc == NULL) |
473 | return 0; | 523 | return; |
474 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 524 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
475 | explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); | 525 | explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); |
476 | else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) | 526 | else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) |
477 | explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); | 527 | explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); |
478 | #ifdef WITH_OPENSSL | 528 | #ifdef WITH_OPENSSL |
479 | else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) | 529 | if (cc->evp != NULL) { |
480 | return SSH_ERR_LIBCRYPTO_ERROR; | 530 | EVP_CIPHER_CTX_free(cc->evp); |
531 | cc->evp = NULL; | ||
532 | } | ||
481 | #endif | 533 | #endif |
482 | return 0; | 534 | explicit_bzero(cc, sizeof(*cc)); |
535 | free(cc); | ||
483 | } | 536 | } |
484 | 537 | ||
485 | /* | 538 | /* |
@@ -487,8 +540,8 @@ cipher_cleanup(struct sshcipher_ctx *cc) | |||
487 | * passphrase and using the resulting 16 bytes as the key. | 540 | * passphrase and using the resulting 16 bytes as the key. |
488 | */ | 541 | */ |
489 | int | 542 | int |
490 | cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher, | 543 | cipher_set_key_string(struct sshcipher_ctx **ccp, |
491 | const char *passphrase, int do_encrypt) | 544 | const struct sshcipher *cipher, const char *passphrase, int do_encrypt) |
492 | { | 545 | { |
493 | u_char digest[16]; | 546 | u_char digest[16]; |
494 | int r = SSH_ERR_INTERNAL_ERROR; | 547 | int r = SSH_ERR_INTERNAL_ERROR; |
@@ -498,7 +551,7 @@ cipher_set_key_string(struct sshcipher_ctx *cc, const struct sshcipher *cipher, | |||
498 | digest, sizeof(digest))) != 0) | 551 | digest, sizeof(digest))) != 0) |
499 | goto out; | 552 | goto out; |
500 | 553 | ||
501 | r = cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt); | 554 | r = cipher_init(ccp, cipher, digest, 16, NULL, 0, do_encrypt); |
502 | out: | 555 | out: |
503 | explicit_bzero(digest, sizeof(digest)); | 556 | explicit_bzero(digest, sizeof(digest)); |
504 | return r; | 557 | return r; |
@@ -523,7 +576,7 @@ cipher_get_keyiv_len(const struct sshcipher_ctx *cc) | |||
523 | ivlen = sizeof(cc->ac_ctx.ctr); | 576 | ivlen = sizeof(cc->ac_ctx.ctr); |
524 | #ifdef WITH_OPENSSL | 577 | #ifdef WITH_OPENSSL |
525 | else | 578 | else |
526 | ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); | 579 | ivlen = EVP_CIPHER_CTX_iv_length(cc->evp); |
527 | #endif /* WITH_OPENSSL */ | 580 | #endif /* WITH_OPENSSL */ |
528 | return (ivlen); | 581 | return (ivlen); |
529 | } | 582 | } |
@@ -555,7 +608,7 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) | |||
555 | case SSH_CIPHER_SSH2: | 608 | case SSH_CIPHER_SSH2: |
556 | case SSH_CIPHER_DES: | 609 | case SSH_CIPHER_DES: |
557 | case SSH_CIPHER_BLOWFISH: | 610 | case SSH_CIPHER_BLOWFISH: |
558 | evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); | 611 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); |
559 | if (evplen == 0) | 612 | if (evplen == 0) |
560 | return 0; | 613 | return 0; |
561 | else if (evplen < 0) | 614 | else if (evplen < 0) |
@@ -568,16 +621,16 @@ cipher_get_keyiv(struct sshcipher_ctx *cc, u_char *iv, u_int len) | |||
568 | else | 621 | else |
569 | #endif | 622 | #endif |
570 | if (cipher_authlen(c)) { | 623 | if (cipher_authlen(c)) { |
571 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, EVP_CTRL_GCM_IV_GEN, | 624 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, EVP_CTRL_GCM_IV_GEN, |
572 | len, iv)) | 625 | len, iv)) |
573 | return SSH_ERR_LIBCRYPTO_ERROR; | 626 | return SSH_ERR_LIBCRYPTO_ERROR; |
574 | } else | 627 | } else |
575 | memcpy(iv, cc->evp.iv, len); | 628 | memcpy(iv, cc->evp->iv, len); |
576 | break; | 629 | break; |
577 | #endif | 630 | #endif |
578 | #ifdef WITH_SSH1 | 631 | #ifdef WITH_SSH1 |
579 | case SSH_CIPHER_3DES: | 632 | case SSH_CIPHER_3DES: |
580 | return ssh1_3des_iv(&cc->evp, 0, iv, 24); | 633 | return ssh1_3des_iv(cc->evp, 0, iv, 24); |
581 | #endif | 634 | #endif |
582 | default: | 635 | default: |
583 | return SSH_ERR_INVALID_ARGUMENT; | 636 | return SSH_ERR_INVALID_ARGUMENT; |
@@ -603,21 +656,21 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) | |||
603 | case SSH_CIPHER_SSH2: | 656 | case SSH_CIPHER_SSH2: |
604 | case SSH_CIPHER_DES: | 657 | case SSH_CIPHER_DES: |
605 | case SSH_CIPHER_BLOWFISH: | 658 | case SSH_CIPHER_BLOWFISH: |
606 | evplen = EVP_CIPHER_CTX_iv_length(&cc->evp); | 659 | evplen = EVP_CIPHER_CTX_iv_length(cc->evp); |
607 | if (evplen <= 0) | 660 | if (evplen <= 0) |
608 | return SSH_ERR_LIBCRYPTO_ERROR; | 661 | return SSH_ERR_LIBCRYPTO_ERROR; |
609 | if (cipher_authlen(c)) { | 662 | if (cipher_authlen(c)) { |
610 | /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ | 663 | /* XXX iv arg is const, but EVP_CIPHER_CTX_ctrl isn't */ |
611 | if (!EVP_CIPHER_CTX_ctrl(&cc->evp, | 664 | if (!EVP_CIPHER_CTX_ctrl(cc->evp, |
612 | EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) | 665 | EVP_CTRL_GCM_SET_IV_FIXED, -1, (void *)iv)) |
613 | return SSH_ERR_LIBCRYPTO_ERROR; | 666 | return SSH_ERR_LIBCRYPTO_ERROR; |
614 | } else | 667 | } else |
615 | memcpy(cc->evp.iv, iv, evplen); | 668 | memcpy(cc->evp->iv, iv, evplen); |
616 | break; | 669 | break; |
617 | #endif | 670 | #endif |
618 | #ifdef WITH_SSH1 | 671 | #ifdef WITH_SSH1 |
619 | case SSH_CIPHER_3DES: | 672 | case SSH_CIPHER_3DES: |
620 | return ssh1_3des_iv(&cc->evp, 1, (u_char *)iv, 24); | 673 | return ssh1_3des_iv(cc->evp, 1, (u_char *)iv, 24); |
621 | #endif | 674 | #endif |
622 | default: | 675 | default: |
623 | return SSH_ERR_INVALID_ARGUMENT; | 676 | return SSH_ERR_INVALID_ARGUMENT; |
@@ -626,8 +679,8 @@ cipher_set_keyiv(struct sshcipher_ctx *cc, const u_char *iv) | |||
626 | } | 679 | } |
627 | 680 | ||
628 | #ifdef WITH_OPENSSL | 681 | #ifdef WITH_OPENSSL |
629 | #define EVP_X_STATE(evp) (evp).cipher_data | 682 | #define EVP_X_STATE(evp) (evp)->cipher_data |
630 | #define EVP_X_STATE_LEN(evp) (evp).cipher->ctx_size | 683 | #define EVP_X_STATE_LEN(evp) (evp)->cipher->ctx_size |
631 | #endif | 684 | #endif |
632 | 685 | ||
633 | int | 686 | int |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.h,v 1.48 2015/07/08 19:09:25 markus Exp $ */ | 1 | /* $OpenBSD: cipher.h,v 1.49 2016/08/03 05:41:57 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -63,14 +63,7 @@ | |||
63 | #define CIPHER_DECRYPT 0 | 63 | #define CIPHER_DECRYPT 0 |
64 | 64 | ||
65 | struct sshcipher; | 65 | struct sshcipher; |
66 | struct sshcipher_ctx { | 66 | struct sshcipher_ctx; |
67 | int plaintext; | ||
68 | int encrypt; | ||
69 | EVP_CIPHER_CTX evp; | ||
70 | struct chachapoly_ctx cp_ctx; /* XXX union with evp? */ | ||
71 | struct aesctr_ctx ac_ctx; /* XXX union with evp? */ | ||
72 | const struct sshcipher *cipher; | ||
73 | }; | ||
74 | 67 | ||
75 | u_int cipher_mask_ssh1(int); | 68 | u_int cipher_mask_ssh1(int); |
76 | const struct sshcipher *cipher_by_name(const char *); | 69 | const struct sshcipher *cipher_by_name(const char *); |
@@ -80,15 +73,15 @@ char *cipher_name(int); | |||
80 | const char *cipher_warning_message(const struct sshcipher_ctx *); | 73 | const char *cipher_warning_message(const struct sshcipher_ctx *); |
81 | int ciphers_valid(const char *); | 74 | int ciphers_valid(const char *); |
82 | char *cipher_alg_list(char, int); | 75 | char *cipher_alg_list(char, int); |
83 | int cipher_init(struct sshcipher_ctx *, const struct sshcipher *, | 76 | int cipher_init(struct sshcipher_ctx **, const struct sshcipher *, |
84 | const u_char *, u_int, const u_char *, u_int, int); | 77 | const u_char *, u_int, const u_char *, u_int, int); |
85 | int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *, | 78 | int cipher_crypt(struct sshcipher_ctx *, u_int, u_char *, const u_char *, |
86 | u_int, u_int, u_int); | 79 | u_int, u_int, u_int); |
87 | int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int, | 80 | int cipher_get_length(struct sshcipher_ctx *, u_int *, u_int, |
88 | const u_char *, u_int); | 81 | const u_char *, u_int); |
89 | int cipher_cleanup(struct sshcipher_ctx *); | 82 | void cipher_free(struct sshcipher_ctx *); |
90 | int cipher_set_key_string(struct sshcipher_ctx *, const struct sshcipher *, | 83 | int cipher_set_key_string(struct sshcipher_ctx **, |
91 | const char *, int); | 84 | const struct sshcipher *, const char *, int); |
92 | u_int cipher_blocksize(const struct sshcipher *); | 85 | u_int cipher_blocksize(const struct sshcipher *); |
93 | u_int cipher_keylen(const struct sshcipher *); | 86 | u_int cipher_keylen(const struct sshcipher *); |
94 | u_int cipher_seclen(const struct sshcipher *); | 87 | u_int cipher_seclen(const struct sshcipher *); |
@@ -96,10 +89,14 @@ u_int cipher_authlen(const struct sshcipher *); | |||
96 | u_int cipher_ivlen(const struct sshcipher *); | 89 | u_int cipher_ivlen(const struct sshcipher *); |
97 | u_int cipher_is_cbc(const struct sshcipher *); | 90 | u_int cipher_is_cbc(const struct sshcipher *); |
98 | 91 | ||
92 | u_int cipher_ctx_is_plaintext(struct sshcipher_ctx *); | ||
93 | u_int cipher_ctx_get_number(struct sshcipher_ctx *); | ||
94 | |||
99 | u_int cipher_get_number(const struct sshcipher *); | 95 | u_int cipher_get_number(const struct sshcipher *); |
100 | int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int); | 96 | int cipher_get_keyiv(struct sshcipher_ctx *, u_char *, u_int); |
101 | int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *); | 97 | int cipher_set_keyiv(struct sshcipher_ctx *, const u_char *); |
102 | int cipher_get_keyiv_len(const struct sshcipher_ctx *); | 98 | int cipher_get_keyiv_len(const struct sshcipher_ctx *); |
103 | int cipher_get_keycontext(const struct sshcipher_ctx *, u_char *); | 99 | int cipher_get_keycontext(const struct sshcipher_ctx *, u_char *); |
104 | void cipher_set_keycontext(struct sshcipher_ctx *, const u_char *); | 100 | void cipher_set_keycontext(struct sshcipher_ctx *, const u_char *); |
101 | |||
105 | #endif /* CIPHER_H */ | 102 | #endif /* CIPHER_H */ |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: packet.c,v 1.234 2016/07/18 11:35:33 markus Exp $ */ | 1 | /* $OpenBSD: packet.c,v 1.235 2016/08/03 05:41:57 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -122,10 +122,10 @@ struct session_state { | |||
122 | u_int remote_protocol_flags; | 122 | u_int remote_protocol_flags; |
123 | 123 | ||
124 | /* Encryption context for receiving data. Only used for decryption. */ | 124 | /* Encryption context for receiving data. Only used for decryption. */ |
125 | struct sshcipher_ctx receive_context; | 125 | struct sshcipher_ctx *receive_context; |
126 | 126 | ||
127 | /* Encryption context for sending data. Only used for encryption. */ | 127 | /* Encryption context for sending data. Only used for encryption. */ |
128 | struct sshcipher_ctx send_context; | 128 | struct sshcipher_ctx *send_context; |
129 | 129 | ||
130 | /* Buffer for raw input data from the socket. */ | 130 | /* Buffer for raw input data from the socket. */ |
131 | struct sshbuf *input; | 131 | struct sshbuf *input; |
@@ -529,7 +529,6 @@ void | |||
529 | ssh_packet_close(struct ssh *ssh) | 529 | ssh_packet_close(struct ssh *ssh) |
530 | { | 530 | { |
531 | struct session_state *state = ssh->state; | 531 | struct session_state *state = ssh->state; |
532 | int r; | ||
533 | u_int mode; | 532 | u_int mode; |
534 | 533 | ||
535 | if (!state->initialized) | 534 | if (!state->initialized) |
@@ -573,10 +572,9 @@ ssh_packet_close(struct ssh *ssh) | |||
573 | inflateEnd(stream); | 572 | inflateEnd(stream); |
574 | } | 573 | } |
575 | } | 574 | } |
576 | if ((r = cipher_cleanup(&state->send_context)) != 0) | 575 | cipher_free(state->send_context); |
577 | error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); | 576 | cipher_free(state->receive_context); |
578 | if ((r = cipher_cleanup(&state->receive_context)) != 0) | 577 | state->send_context = state->receive_context = NULL; |
579 | error("%s: cipher_cleanup failed: %s", __func__, ssh_err(r)); | ||
580 | free(ssh->remote_ipaddr); | 578 | free(ssh->remote_ipaddr); |
581 | ssh->remote_ipaddr = NULL; | 579 | ssh->remote_ipaddr = NULL; |
582 | free(ssh->state); | 580 | free(ssh->state); |
@@ -870,8 +868,8 @@ ssh_packet_set_encryption_key(struct ssh *ssh, const u_char *key, u_int keylen, | |||
870 | NULL, 0, CIPHER_DECRYPT) != 0)) | 868 | NULL, 0, CIPHER_DECRYPT) != 0)) |
871 | fatal("%s: cipher_init failed: %s", __func__, ssh_err(r)); | 869 | fatal("%s: cipher_init failed: %s", __func__, ssh_err(r)); |
872 | if (!state->cipher_warning_done && | 870 | if (!state->cipher_warning_done && |
873 | ((wmsg = cipher_warning_message(&state->send_context)) != NULL || | 871 | ((wmsg = cipher_warning_message(state->send_context)) != NULL || |
874 | (wmsg = cipher_warning_message(&state->send_context)) != NULL)) { | 872 | (wmsg = cipher_warning_message(state->send_context)) != NULL)) { |
875 | error("Warning: %s", wmsg); | 873 | error("Warning: %s", wmsg); |
876 | state->cipher_warning_done = 1; | 874 | state->cipher_warning_done = 1; |
877 | } | 875 | } |
@@ -917,7 +915,7 @@ ssh_packet_send1(struct ssh *ssh) | |||
917 | 915 | ||
918 | /* Insert padding. Initialized to zero in packet_start1() */ | 916 | /* Insert padding. Initialized to zero in packet_start1() */ |
919 | padding = 8 - len % 8; | 917 | padding = 8 - len % 8; |
920 | if (!state->send_context.plaintext) { | 918 | if (!cipher_ctx_is_plaintext(state->send_context)) { |
921 | cp = sshbuf_mutable_ptr(state->outgoing_packet); | 919 | cp = sshbuf_mutable_ptr(state->outgoing_packet); |
922 | if (cp == NULL) { | 920 | if (cp == NULL) { |
923 | r = SSH_ERR_INTERNAL_ERROR; | 921 | r = SSH_ERR_INTERNAL_ERROR; |
@@ -947,7 +945,7 @@ ssh_packet_send1(struct ssh *ssh) | |||
947 | if ((r = sshbuf_reserve(state->output, | 945 | if ((r = sshbuf_reserve(state->output, |
948 | sshbuf_len(state->outgoing_packet), &cp)) != 0) | 946 | sshbuf_len(state->outgoing_packet), &cp)) != 0) |
949 | goto out; | 947 | goto out; |
950 | if ((r = cipher_crypt(&state->send_context, 0, cp, | 948 | if ((r = cipher_crypt(state->send_context, 0, cp, |
951 | sshbuf_ptr(state->outgoing_packet), | 949 | sshbuf_ptr(state->outgoing_packet), |
952 | sshbuf_len(state->outgoing_packet), 0, 0)) != 0) | 950 | sshbuf_len(state->outgoing_packet), 0, 0)) != 0) |
953 | goto out; | 951 | goto out; |
@@ -978,7 +976,7 @@ ssh_set_newkeys(struct ssh *ssh, int mode) | |||
978 | struct sshenc *enc; | 976 | struct sshenc *enc; |
979 | struct sshmac *mac; | 977 | struct sshmac *mac; |
980 | struct sshcomp *comp; | 978 | struct sshcomp *comp; |
981 | struct sshcipher_ctx *cc; | 979 | struct sshcipher_ctx **ccp; |
982 | u_int64_t *max_blocks; | 980 | u_int64_t *max_blocks; |
983 | const char *wmsg; | 981 | const char *wmsg; |
984 | int r, crypt_type; | 982 | int r, crypt_type; |
@@ -986,12 +984,12 @@ ssh_set_newkeys(struct ssh *ssh, int mode) | |||
986 | debug2("set_newkeys: mode %d", mode); | 984 | debug2("set_newkeys: mode %d", mode); |
987 | 985 | ||
988 | if (mode == MODE_OUT) { | 986 | if (mode == MODE_OUT) { |
989 | cc = &state->send_context; | 987 | ccp = &state->send_context; |
990 | crypt_type = CIPHER_ENCRYPT; | 988 | crypt_type = CIPHER_ENCRYPT; |
991 | state->p_send.packets = state->p_send.blocks = 0; | 989 | state->p_send.packets = state->p_send.blocks = 0; |
992 | max_blocks = &state->max_blocks_out; | 990 | max_blocks = &state->max_blocks_out; |
993 | } else { | 991 | } else { |
994 | cc = &state->receive_context; | 992 | ccp = &state->receive_context; |
995 | crypt_type = CIPHER_DECRYPT; | 993 | crypt_type = CIPHER_DECRYPT; |
996 | state->p_read.packets = state->p_read.blocks = 0; | 994 | state->p_read.packets = state->p_read.blocks = 0; |
997 | max_blocks = &state->max_blocks_in; | 995 | max_blocks = &state->max_blocks_in; |
@@ -1003,8 +1001,8 @@ ssh_set_newkeys(struct ssh *ssh, int mode) | |||
1003 | (unsigned long long)state->p_read.blocks, | 1001 | (unsigned long long)state->p_read.blocks, |
1004 | (unsigned long long)state->p_send.bytes, | 1002 | (unsigned long long)state->p_send.bytes, |
1005 | (unsigned long long)state->p_send.blocks); | 1003 | (unsigned long long)state->p_send.blocks); |
1006 | if ((r = cipher_cleanup(cc)) != 0) | 1004 | cipher_free(*ccp); |
1007 | return r; | 1005 | *ccp = NULL; |
1008 | enc = &state->newkeys[mode]->enc; | 1006 | enc = &state->newkeys[mode]->enc; |
1009 | mac = &state->newkeys[mode]->mac; | 1007 | mac = &state->newkeys[mode]->mac; |
1010 | comp = &state->newkeys[mode]->comp; | 1008 | comp = &state->newkeys[mode]->comp; |
@@ -1033,11 +1031,11 @@ ssh_set_newkeys(struct ssh *ssh, int mode) | |||
1033 | } | 1031 | } |
1034 | mac->enabled = 1; | 1032 | mac->enabled = 1; |
1035 | DBG(debug("cipher_init_context: %d", mode)); | 1033 | DBG(debug("cipher_init_context: %d", mode)); |
1036 | if ((r = cipher_init(cc, enc->cipher, enc->key, enc->key_len, | 1034 | if ((r = cipher_init(ccp, enc->cipher, enc->key, enc->key_len, |
1037 | enc->iv, enc->iv_len, crypt_type)) != 0) | 1035 | enc->iv, enc->iv_len, crypt_type)) != 0) |
1038 | return r; | 1036 | return r; |
1039 | if (!state->cipher_warning_done && | 1037 | if (!state->cipher_warning_done && |
1040 | (wmsg = cipher_warning_message(cc)) != NULL) { | 1038 | (wmsg = cipher_warning_message(*ccp)) != NULL) { |
1041 | error("Warning: %s", wmsg); | 1039 | error("Warning: %s", wmsg); |
1042 | state->cipher_warning_done = 1; | 1040 | state->cipher_warning_done = 1; |
1043 | } | 1041 | } |
@@ -1259,7 +1257,7 @@ ssh_packet_send2_wrapped(struct ssh *ssh) | |||
1259 | } | 1257 | } |
1260 | if ((r = sshbuf_reserve(state->outgoing_packet, padlen, &cp)) != 0) | 1258 | if ((r = sshbuf_reserve(state->outgoing_packet, padlen, &cp)) != 0) |
1261 | goto out; | 1259 | goto out; |
1262 | if (enc && !state->send_context.plaintext) { | 1260 | if (enc && !cipher_ctx_is_plaintext(state->send_context)) { |
1263 | /* random padding */ | 1261 | /* random padding */ |
1264 | arc4random_buf(cp, padlen); | 1262 | arc4random_buf(cp, padlen); |
1265 | } else { | 1263 | } else { |
@@ -1291,7 +1289,7 @@ ssh_packet_send2_wrapped(struct ssh *ssh) | |||
1291 | if ((r = sshbuf_reserve(state->output, | 1289 | if ((r = sshbuf_reserve(state->output, |
1292 | sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) | 1290 | sshbuf_len(state->outgoing_packet) + authlen, &cp)) != 0) |
1293 | goto out; | 1291 | goto out; |
1294 | if ((r = cipher_crypt(&state->send_context, state->p_send.seqnr, cp, | 1292 | if ((r = cipher_crypt(state->send_context, state->p_send.seqnr, cp, |
1295 | sshbuf_ptr(state->outgoing_packet), | 1293 | sshbuf_ptr(state->outgoing_packet), |
1296 | len - aadlen, aadlen, authlen)) != 0) | 1294 | len - aadlen, aadlen, authlen)) != 0) |
1297 | goto out; | 1295 | goto out; |
@@ -1606,7 +1604,7 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) | |||
1606 | * (C)1998 CORE-SDI, Buenos Aires Argentina | 1604 | * (C)1998 CORE-SDI, Buenos Aires Argentina |
1607 | * Ariel Futoransky(futo@core-sdi.com) | 1605 | * Ariel Futoransky(futo@core-sdi.com) |
1608 | */ | 1606 | */ |
1609 | if (!state->receive_context.plaintext) { | 1607 | if (!cipher_ctx_is_plaintext(state->receive_context)) { |
1610 | emsg = NULL; | 1608 | emsg = NULL; |
1611 | switch (detect_attack(&state->deattack, | 1609 | switch (detect_attack(&state->deattack, |
1612 | sshbuf_ptr(state->input), padded_len)) { | 1610 | sshbuf_ptr(state->input), padded_len)) { |
@@ -1635,7 +1633,7 @@ ssh_packet_read_poll1(struct ssh *ssh, u_char *typep) | |||
1635 | sshbuf_reset(state->incoming_packet); | 1633 | sshbuf_reset(state->incoming_packet); |
1636 | if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0) | 1634 | if ((r = sshbuf_reserve(state->incoming_packet, padded_len, &p)) != 0) |
1637 | goto out; | 1635 | goto out; |
1638 | if ((r = cipher_crypt(&state->receive_context, 0, p, | 1636 | if ((r = cipher_crypt(state->receive_context, 0, p, |
1639 | sshbuf_ptr(state->input), padded_len, 0, 0)) != 0) | 1637 | sshbuf_ptr(state->input), padded_len, 0, 0)) != 0) |
1640 | goto out; | 1638 | goto out; |
1641 | 1639 | ||
@@ -1733,7 +1731,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1733 | aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; | 1731 | aadlen = (mac && mac->enabled && mac->etm) || authlen ? 4 : 0; |
1734 | 1732 | ||
1735 | if (aadlen && state->packlen == 0) { | 1733 | if (aadlen && state->packlen == 0) { |
1736 | if (cipher_get_length(&state->receive_context, | 1734 | if (cipher_get_length(state->receive_context, |
1737 | &state->packlen, state->p_read.seqnr, | 1735 | &state->packlen, state->p_read.seqnr, |
1738 | sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0) | 1736 | sshbuf_ptr(state->input), sshbuf_len(state->input)) != 0) |
1739 | return 0; | 1737 | return 0; |
@@ -1759,7 +1757,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1759 | if ((r = sshbuf_reserve(state->incoming_packet, block_size, | 1757 | if ((r = sshbuf_reserve(state->incoming_packet, block_size, |
1760 | &cp)) != 0) | 1758 | &cp)) != 0) |
1761 | goto out; | 1759 | goto out; |
1762 | if ((r = cipher_crypt(&state->receive_context, | 1760 | if ((r = cipher_crypt(state->receive_context, |
1763 | state->p_send.seqnr, cp, sshbuf_ptr(state->input), | 1761 | state->p_send.seqnr, cp, sshbuf_ptr(state->input), |
1764 | block_size, 0, 0)) != 0) | 1762 | block_size, 0, 0)) != 0) |
1765 | goto out; | 1763 | goto out; |
@@ -1827,7 +1825,7 @@ ssh_packet_read_poll2(struct ssh *ssh, u_char *typep, u_int32_t *seqnr_p) | |||
1827 | if ((r = sshbuf_reserve(state->incoming_packet, aadlen + need, | 1825 | if ((r = sshbuf_reserve(state->incoming_packet, aadlen + need, |
1828 | &cp)) != 0) | 1826 | &cp)) != 0) |
1829 | goto out; | 1827 | goto out; |
1830 | if ((r = cipher_crypt(&state->receive_context, state->p_read.seqnr, cp, | 1828 | if ((r = cipher_crypt(state->receive_context, state->p_read.seqnr, cp, |
1831 | sshbuf_ptr(state->input), need, aadlen, authlen)) != 0) | 1829 | sshbuf_ptr(state->input), need, aadlen, authlen)) != 0) |
1832 | goto out; | 1830 | goto out; |
1833 | if ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0) | 1831 | if ((r = sshbuf_consume(state->input, aadlen + need + authlen)) != 0) |
@@ -2509,8 +2507,8 @@ newkeys_to_blob(struct sshbuf *m, struct ssh *ssh, int mode) | |||
2509 | enc = &newkey->enc; | 2507 | enc = &newkey->enc; |
2510 | mac = &newkey->mac; | 2508 | mac = &newkey->mac; |
2511 | comp = &newkey->comp; | 2509 | comp = &newkey->comp; |
2512 | cc = (mode == MODE_OUT) ? &ssh->state->send_context : | 2510 | cc = (mode == MODE_OUT) ? ssh->state->send_context : |
2513 | &ssh->state->receive_context; | 2511 | ssh->state->receive_context; |
2514 | if ((r = cipher_get_keyiv(cc, enc->iv, enc->iv_len)) != 0) | 2512 | if ((r = cipher_get_keyiv(cc, enc->iv, enc->iv_len)) != 0) |
2515 | return r; | 2513 | return r; |
2516 | if ((b = sshbuf_new()) == NULL) | 2514 | if ((b = sshbuf_new()) == NULL) |
@@ -2549,18 +2547,18 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) | |||
2549 | int r, ssh1cipher; | 2547 | int r, ssh1cipher; |
2550 | 2548 | ||
2551 | if (!compat20) { | 2549 | if (!compat20) { |
2552 | ssh1cipher = cipher_get_number(state->receive_context.cipher); | 2550 | ssh1cipher = cipher_ctx_get_number(state->receive_context); |
2553 | slen = cipher_get_keyiv_len(&state->send_context); | 2551 | slen = cipher_get_keyiv_len(state->send_context); |
2554 | rlen = cipher_get_keyiv_len(&state->receive_context); | 2552 | rlen = cipher_get_keyiv_len(state->receive_context); |
2555 | if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 || | 2553 | if ((r = sshbuf_put_u32(m, state->remote_protocol_flags)) != 0 || |
2556 | (r = sshbuf_put_u32(m, ssh1cipher)) != 0 || | 2554 | (r = sshbuf_put_u32(m, ssh1cipher)) != 0 || |
2557 | (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 || | 2555 | (r = sshbuf_put_string(m, state->ssh1_key, state->ssh1_keylen)) != 0 || |
2558 | (r = sshbuf_put_u32(m, slen)) != 0 || | 2556 | (r = sshbuf_put_u32(m, slen)) != 0 || |
2559 | (r = sshbuf_reserve(m, slen, &p)) != 0 || | 2557 | (r = sshbuf_reserve(m, slen, &p)) != 0 || |
2560 | (r = cipher_get_keyiv(&state->send_context, p, slen)) != 0 || | 2558 | (r = cipher_get_keyiv(state->send_context, p, slen)) != 0 || |
2561 | (r = sshbuf_put_u32(m, rlen)) != 0 || | 2559 | (r = sshbuf_put_u32(m, rlen)) != 0 || |
2562 | (r = sshbuf_reserve(m, rlen, &p)) != 0 || | 2560 | (r = sshbuf_reserve(m, rlen, &p)) != 0 || |
2563 | (r = cipher_get_keyiv(&state->receive_context, p, rlen)) != 0) | 2561 | (r = cipher_get_keyiv(state->receive_context, p, rlen)) != 0) |
2564 | return r; | 2562 | return r; |
2565 | } else { | 2563 | } else { |
2566 | if ((r = kex_to_blob(m, ssh->kex)) != 0 || | 2564 | if ((r = kex_to_blob(m, ssh->kex)) != 0 || |
@@ -2579,17 +2577,17 @@ ssh_packet_get_state(struct ssh *ssh, struct sshbuf *m) | |||
2579 | return r; | 2577 | return r; |
2580 | } | 2578 | } |
2581 | 2579 | ||
2582 | slen = cipher_get_keycontext(&state->send_context, NULL); | 2580 | slen = cipher_get_keycontext(state->send_context, NULL); |
2583 | rlen = cipher_get_keycontext(&state->receive_context, NULL); | 2581 | rlen = cipher_get_keycontext(state->receive_context, NULL); |
2584 | if ((r = sshbuf_put_u32(m, slen)) != 0 || | 2582 | if ((r = sshbuf_put_u32(m, slen)) != 0 || |
2585 | (r = sshbuf_reserve(m, slen, &p)) != 0) | 2583 | (r = sshbuf_reserve(m, slen, &p)) != 0) |
2586 | return r; | 2584 | return r; |
2587 | if (cipher_get_keycontext(&state->send_context, p) != (int)slen) | 2585 | if (cipher_get_keycontext(state->send_context, p) != (int)slen) |
2588 | return SSH_ERR_INTERNAL_ERROR; | 2586 | return SSH_ERR_INTERNAL_ERROR; |
2589 | if ((r = sshbuf_put_u32(m, rlen)) != 0 || | 2587 | if ((r = sshbuf_put_u32(m, rlen)) != 0 || |
2590 | (r = sshbuf_reserve(m, rlen, &p)) != 0) | 2588 | (r = sshbuf_reserve(m, rlen, &p)) != 0) |
2591 | return r; | 2589 | return r; |
2592 | if (cipher_get_keycontext(&state->receive_context, p) != (int)rlen) | 2590 | if (cipher_get_keycontext(state->receive_context, p) != (int)rlen) |
2593 | return SSH_ERR_INTERNAL_ERROR; | 2591 | return SSH_ERR_INTERNAL_ERROR; |
2594 | 2592 | ||
2595 | if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 || | 2593 | if ((r = ssh_packet_get_compress_state(m, ssh)) != 0 || |
@@ -2735,11 +2733,11 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) | |||
2735 | return SSH_ERR_KEY_UNKNOWN_CIPHER; | 2733 | return SSH_ERR_KEY_UNKNOWN_CIPHER; |
2736 | ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen, | 2734 | ssh_packet_set_encryption_key(ssh, ssh1key, ssh1keylen, |
2737 | (int)ssh1cipher); | 2735 | (int)ssh1cipher); |
2738 | if (cipher_get_keyiv_len(&state->send_context) != (int)slen || | 2736 | if (cipher_get_keyiv_len(state->send_context) != (int)slen || |
2739 | cipher_get_keyiv_len(&state->receive_context) != (int)rlen) | 2737 | cipher_get_keyiv_len(state->receive_context) != (int)rlen) |
2740 | return SSH_ERR_INVALID_FORMAT; | 2738 | return SSH_ERR_INVALID_FORMAT; |
2741 | if ((r = cipher_set_keyiv(&state->send_context, ivout)) != 0 || | 2739 | if ((r = cipher_set_keyiv(state->send_context, ivout)) != 0 || |
2742 | (r = cipher_set_keyiv(&state->receive_context, ivin)) != 0) | 2740 | (r = cipher_set_keyiv(state->receive_context, ivin)) != 0) |
2743 | return r; | 2741 | return r; |
2744 | } else { | 2742 | } else { |
2745 | if ((r = kex_from_blob(m, &ssh->kex)) != 0 || | 2743 | if ((r = kex_from_blob(m, &ssh->kex)) != 0 || |
@@ -2769,11 +2767,11 @@ ssh_packet_set_state(struct ssh *ssh, struct sshbuf *m) | |||
2769 | if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 || | 2767 | if ((r = sshbuf_get_string_direct(m, &keyout, &slen)) != 0 || |
2770 | (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0) | 2768 | (r = sshbuf_get_string_direct(m, &keyin, &rlen)) != 0) |
2771 | return r; | 2769 | return r; |
2772 | if (cipher_get_keycontext(&state->send_context, NULL) != (int)slen || | 2770 | if (cipher_get_keycontext(state->send_context, NULL) != (int)slen || |
2773 | cipher_get_keycontext(&state->receive_context, NULL) != (int)rlen) | 2771 | cipher_get_keycontext(state->receive_context, NULL) != (int)rlen) |
2774 | return SSH_ERR_INVALID_FORMAT; | 2772 | return SSH_ERR_INVALID_FORMAT; |
2775 | cipher_set_keycontext(&state->send_context, keyout); | 2773 | cipher_set_keycontext(state->send_context, keyout); |
2776 | cipher_set_keycontext(&state->receive_context, keyin); | 2774 | cipher_set_keycontext(state->receive_context, keyin); |
2777 | 2775 | ||
2778 | if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 || | 2776 | if ((r = ssh_packet_set_compress_state(ssh, m)) != 0 || |
2779 | (r = ssh_packet_set_postauth(ssh)) != 0) | 2777 | (r = ssh_packet_set_postauth(ssh)) != 0) |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: sshkey.c,v 1.35 2016/06/19 07:48:02 djm Exp $ */ | 1 | /* $OpenBSD: sshkey.c,v 1.36 2016/08/03 05:41:57 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. | 4 | * Copyright (c) 2008 Alexander von Gernler. All rights reserved. |
@@ -3029,13 +3029,11 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, | |||
3029 | size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; | 3029 | size_t i, pubkeylen, keylen, ivlen, blocksize, authlen; |
3030 | u_int check; | 3030 | u_int check; |
3031 | int r = SSH_ERR_INTERNAL_ERROR; | 3031 | int r = SSH_ERR_INTERNAL_ERROR; |
3032 | struct sshcipher_ctx ciphercontext; | 3032 | struct sshcipher_ctx *ciphercontext = NULL; |
3033 | const struct sshcipher *cipher; | 3033 | const struct sshcipher *cipher; |
3034 | const char *kdfname = KDFNAME; | 3034 | const char *kdfname = KDFNAME; |
3035 | struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; | 3035 | struct sshbuf *encoded = NULL, *encrypted = NULL, *kdf = NULL; |
3036 | 3036 | ||
3037 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | ||
3038 | |||
3039 | if (rounds <= 0) | 3037 | if (rounds <= 0) |
3040 | rounds = DEFAULT_ROUNDS; | 3038 | rounds = DEFAULT_ROUNDS; |
3041 | if (passphrase == NULL || !strlen(passphrase)) { | 3039 | if (passphrase == NULL || !strlen(passphrase)) { |
@@ -3122,7 +3120,7 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, | |||
3122 | if ((r = sshbuf_reserve(encoded, | 3120 | if ((r = sshbuf_reserve(encoded, |
3123 | sshbuf_len(encrypted) + authlen, &cp)) != 0) | 3121 | sshbuf_len(encrypted) + authlen, &cp)) != 0) |
3124 | goto out; | 3122 | goto out; |
3125 | if ((r = cipher_crypt(&ciphercontext, 0, cp, | 3123 | if ((r = cipher_crypt(ciphercontext, 0, cp, |
3126 | sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) | 3124 | sshbuf_ptr(encrypted), sshbuf_len(encrypted), 0, authlen)) != 0) |
3127 | goto out; | 3125 | goto out; |
3128 | 3126 | ||
@@ -3154,7 +3152,7 @@ sshkey_private_to_blob2(const struct sshkey *prv, struct sshbuf *blob, | |||
3154 | sshbuf_free(kdf); | 3152 | sshbuf_free(kdf); |
3155 | sshbuf_free(encoded); | 3153 | sshbuf_free(encoded); |
3156 | sshbuf_free(encrypted); | 3154 | sshbuf_free(encrypted); |
3157 | cipher_cleanup(&ciphercontext); | 3155 | cipher_free(ciphercontext); |
3158 | explicit_bzero(salt, sizeof(salt)); | 3156 | explicit_bzero(salt, sizeof(salt)); |
3159 | if (key != NULL) { | 3157 | if (key != NULL) { |
3160 | explicit_bzero(key, keylen + ivlen); | 3158 | explicit_bzero(key, keylen + ivlen); |
@@ -3183,12 +3181,11 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, | |||
3183 | size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0; | 3181 | size_t i, keylen = 0, ivlen = 0, authlen = 0, slen = 0; |
3184 | struct sshbuf *encoded = NULL, *decoded = NULL; | 3182 | struct sshbuf *encoded = NULL, *decoded = NULL; |
3185 | struct sshbuf *kdf = NULL, *decrypted = NULL; | 3183 | struct sshbuf *kdf = NULL, *decrypted = NULL; |
3186 | struct sshcipher_ctx ciphercontext; | 3184 | struct sshcipher_ctx *ciphercontext = NULL; |
3187 | struct sshkey *k = NULL; | 3185 | struct sshkey *k = NULL; |
3188 | u_char *key = NULL, *salt = NULL, *dp, pad, last; | 3186 | u_char *key = NULL, *salt = NULL, *dp, pad, last; |
3189 | u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; | 3187 | u_int blocksize, rounds, nkeys, encrypted_len, check1, check2; |
3190 | 3188 | ||
3191 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | ||
3192 | if (keyp != NULL) | 3189 | if (keyp != NULL) |
3193 | *keyp = NULL; | 3190 | *keyp = NULL; |
3194 | if (commentp != NULL) | 3191 | if (commentp != NULL) |
@@ -3317,7 +3314,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, | |||
3317 | (r = cipher_init(&ciphercontext, cipher, key, keylen, | 3314 | (r = cipher_init(&ciphercontext, cipher, key, keylen, |
3318 | key + keylen, ivlen, 0)) != 0) | 3315 | key + keylen, ivlen, 0)) != 0) |
3319 | goto out; | 3316 | goto out; |
3320 | if ((r = cipher_crypt(&ciphercontext, 0, dp, sshbuf_ptr(decoded), | 3317 | if ((r = cipher_crypt(ciphercontext, 0, dp, sshbuf_ptr(decoded), |
3321 | encrypted_len, 0, authlen)) != 0) { | 3318 | encrypted_len, 0, authlen)) != 0) { |
3322 | /* an integrity error here indicates an incorrect passphrase */ | 3319 | /* an integrity error here indicates an incorrect passphrase */ |
3323 | if (r == SSH_ERR_MAC_INVALID) | 3320 | if (r == SSH_ERR_MAC_INVALID) |
@@ -3371,7 +3368,7 @@ sshkey_parse_private2(struct sshbuf *blob, int type, const char *passphrase, | |||
3371 | } | 3368 | } |
3372 | out: | 3369 | out: |
3373 | pad = 0; | 3370 | pad = 0; |
3374 | cipher_cleanup(&ciphercontext); | 3371 | cipher_free(ciphercontext); |
3375 | free(ciphername); | 3372 | free(ciphername); |
3376 | free(kdfname); | 3373 | free(kdfname); |
3377 | free(comment); | 3374 | free(comment); |
@@ -3405,7 +3402,7 @@ sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, | |||
3405 | struct sshbuf *buffer = NULL, *encrypted = NULL; | 3402 | struct sshbuf *buffer = NULL, *encrypted = NULL; |
3406 | u_char buf[8]; | 3403 | u_char buf[8]; |
3407 | int r, cipher_num; | 3404 | int r, cipher_num; |
3408 | struct sshcipher_ctx ciphercontext; | 3405 | struct sshcipher_ctx *ciphercontext = NULL; |
3409 | const struct sshcipher *cipher; | 3406 | const struct sshcipher *cipher; |
3410 | u_char *cp; | 3407 | u_char *cp; |
3411 | 3408 | ||
@@ -3475,16 +3472,14 @@ sshkey_private_rsa1_to_blob(struct sshkey *key, struct sshbuf *blob, | |||
3475 | if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, | 3472 | if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, |
3476 | CIPHER_ENCRYPT)) != 0) | 3473 | CIPHER_ENCRYPT)) != 0) |
3477 | goto out; | 3474 | goto out; |
3478 | if ((r = cipher_crypt(&ciphercontext, 0, cp, | 3475 | if ((r = cipher_crypt(ciphercontext, 0, cp, |
3479 | sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0) | 3476 | sshbuf_ptr(buffer), sshbuf_len(buffer), 0, 0)) != 0) |
3480 | goto out; | 3477 | goto out; |
3481 | if ((r = cipher_cleanup(&ciphercontext)) != 0) | ||
3482 | goto out; | ||
3483 | 3478 | ||
3484 | r = sshbuf_putb(blob, encrypted); | 3479 | r = sshbuf_putb(blob, encrypted); |
3485 | 3480 | ||
3486 | out: | 3481 | out: |
3487 | explicit_bzero(&ciphercontext, sizeof(ciphercontext)); | 3482 | cipher_free(ciphercontext); |
3488 | explicit_bzero(buf, sizeof(buf)); | 3483 | explicit_bzero(buf, sizeof(buf)); |
3489 | sshbuf_free(buffer); | 3484 | sshbuf_free(buffer); |
3490 | sshbuf_free(encrypted); | 3485 | sshbuf_free(encrypted); |
@@ -3654,7 +3649,7 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, | |||
3654 | struct sshbuf *decrypted = NULL, *copy = NULL; | 3649 | struct sshbuf *decrypted = NULL, *copy = NULL; |
3655 | u_char *cp; | 3650 | u_char *cp; |
3656 | char *comment = NULL; | 3651 | char *comment = NULL; |
3657 | struct sshcipher_ctx ciphercontext; | 3652 | struct sshcipher_ctx *ciphercontext = NULL; |
3658 | const struct sshcipher *cipher; | 3653 | const struct sshcipher *cipher; |
3659 | struct sshkey *prv = NULL; | 3654 | struct sshkey *prv = NULL; |
3660 | 3655 | ||
@@ -3712,12 +3707,8 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, | |||
3712 | if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, | 3707 | if ((r = cipher_set_key_string(&ciphercontext, cipher, passphrase, |
3713 | CIPHER_DECRYPT)) != 0) | 3708 | CIPHER_DECRYPT)) != 0) |
3714 | goto out; | 3709 | goto out; |
3715 | if ((r = cipher_crypt(&ciphercontext, 0, cp, | 3710 | if ((r = cipher_crypt(ciphercontext, 0, cp, |
3716 | sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) { | 3711 | sshbuf_ptr(copy), sshbuf_len(copy), 0, 0)) != 0) |
3717 | cipher_cleanup(&ciphercontext); | ||
3718 | goto out; | ||
3719 | } | ||
3720 | if ((r = cipher_cleanup(&ciphercontext)) != 0) | ||
3721 | goto out; | 3712 | goto out; |
3722 | 3713 | ||
3723 | if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 || | 3714 | if ((r = sshbuf_get_u16(decrypted, &check1)) != 0 || |
@@ -3754,7 +3745,7 @@ sshkey_parse_private_rsa1(struct sshbuf *blob, const char *passphrase, | |||
3754 | comment = NULL; | 3745 | comment = NULL; |
3755 | } | 3746 | } |
3756 | out: | 3747 | out: |
3757 | explicit_bzero(&ciphercontext, sizeof(ciphercontext)); | 3748 | cipher_free(ciphercontext); |
3758 | free(comment); | 3749 | free(comment); |
3759 | sshkey_free(prv); | 3750 | sshkey_free(prv); |
3760 | sshbuf_free(copy); | 3751 | sshbuf_free(copy); |