diff options
Diffstat (limited to 'cipher.c')
-rw-r--r-- | cipher.c | 88 |
1 files changed, 80 insertions, 8 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: cipher.c,v 1.97 2014/02/07 06:55:54 djm Exp $ */ | 1 | /* $OpenBSD: cipher.c,v 1.98 2014/04/29 18:01:49 markus 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 |
@@ -53,9 +53,11 @@ | |||
53 | /* compatibility with old or broken OpenSSL versions */ | 53 | /* compatibility with old or broken OpenSSL versions */ |
54 | #include "openbsd-compat/openssl-compat.h" | 54 | #include "openbsd-compat/openssl-compat.h" |
55 | 55 | ||
56 | #ifdef WITH_SSH1 | ||
56 | extern const EVP_CIPHER *evp_ssh1_bf(void); | 57 | extern const EVP_CIPHER *evp_ssh1_bf(void); |
57 | extern const EVP_CIPHER *evp_ssh1_3des(void); | 58 | extern const EVP_CIPHER *evp_ssh1_3des(void); |
58 | extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); | 59 | extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int); |
60 | #endif | ||
59 | 61 | ||
60 | struct Cipher { | 62 | struct Cipher { |
61 | char *name; | 63 | char *name; |
@@ -68,15 +70,23 @@ struct Cipher { | |||
68 | u_int flags; | 70 | u_int flags; |
69 | #define CFLAG_CBC (1<<0) | 71 | #define CFLAG_CBC (1<<0) |
70 | #define CFLAG_CHACHAPOLY (1<<1) | 72 | #define CFLAG_CHACHAPOLY (1<<1) |
73 | #define CFLAG_AESCTR (1<<2) | ||
74 | #define CFLAG_NONE (1<<3) | ||
75 | #ifdef WITH_OPENSSL | ||
71 | const EVP_CIPHER *(*evptype)(void); | 76 | const EVP_CIPHER *(*evptype)(void); |
77 | #else | ||
78 | void *ignored; | ||
79 | #endif | ||
72 | }; | 80 | }; |
73 | 81 | ||
74 | static const struct Cipher ciphers[] = { | 82 | static const struct Cipher ciphers[] = { |
75 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, | 83 | #ifdef WITH_SSH1 |
76 | { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, | 84 | { "des", SSH_CIPHER_DES, 8, 8, 0, 0, 0, 1, EVP_des_cbc }, |
77 | { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, | 85 | { "3des", SSH_CIPHER_3DES, 8, 16, 0, 0, 0, 1, evp_ssh1_3des }, |
78 | { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, | 86 | { "blowfish", SSH_CIPHER_BLOWFISH, 8, 32, 0, 0, 0, 1, evp_ssh1_bf }, |
79 | 87 | #endif | |
88 | #ifdef WITH_OPENSSL | ||
89 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, 0, EVP_enc_null }, | ||
80 | { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, | 90 | { "3des-cbc", SSH_CIPHER_SSH2, 8, 24, 0, 0, 0, 1, EVP_des_ede3_cbc }, |
81 | { "blowfish-cbc", | 91 | { "blowfish-cbc", |
82 | SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, | 92 | SSH_CIPHER_SSH2, 8, 16, 0, 0, 0, 1, EVP_bf_cbc }, |
@@ -99,6 +109,12 @@ static const struct Cipher ciphers[] = { | |||
99 | { "aes256-gcm@openssh.com", | 109 | { "aes256-gcm@openssh.com", |
100 | SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, | 110 | SSH_CIPHER_SSH2, 16, 32, 12, 16, 0, 0, EVP_aes_256_gcm }, |
101 | #endif | 111 | #endif |
112 | #else /* WITH_OPENSSL */ | ||
113 | { "aes128-ctr", SSH_CIPHER_SSH2, 16, 16, 0, 0, 0, CFLAG_AESCTR, NULL }, | ||
114 | { "aes192-ctr", SSH_CIPHER_SSH2, 16, 24, 0, 0, 0, CFLAG_AESCTR, NULL }, | ||
115 | { "aes256-ctr", SSH_CIPHER_SSH2, 16, 32, 0, 0, 0, CFLAG_AESCTR, NULL }, | ||
116 | { "none", SSH_CIPHER_NONE, 8, 0, 0, 0, 0, CFLAG_NONE, NULL }, | ||
117 | #endif /* WITH_OPENSSL */ | ||
102 | { "chacha20-poly1305@openssh.com", | 118 | { "chacha20-poly1305@openssh.com", |
103 | SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, | 119 | SSH_CIPHER_SSH2, 8, 64, 0, 16, 0, CFLAG_CHACHAPOLY, NULL }, |
104 | { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } | 120 | { NULL, SSH_CIPHER_INVALID, 0, 0, 0, 0, 0, 0, NULL } |
@@ -264,6 +280,7 @@ cipher_init(CipherContext *cc, const Cipher *cipher, | |||
264 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, | 280 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen, |
265 | int do_encrypt) | 281 | int do_encrypt) |
266 | { | 282 | { |
283 | #ifdef WITH_OPENSSL | ||
267 | static int dowarn = 1; | 284 | static int dowarn = 1; |
268 | #ifdef SSH_OLD_EVP | 285 | #ifdef SSH_OLD_EVP |
269 | EVP_CIPHER *type; | 286 | EVP_CIPHER *type; |
@@ -282,6 +299,7 @@ cipher_init(CipherContext *cc, const Cipher *cipher, | |||
282 | if (keylen > 8) | 299 | if (keylen > 8) |
283 | keylen = 8; | 300 | keylen = 8; |
284 | } | 301 | } |
302 | #endif | ||
285 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); | 303 | cc->plaintext = (cipher->number == SSH_CIPHER_NONE); |
286 | cc->encrypt = do_encrypt; | 304 | cc->encrypt = do_encrypt; |
287 | 305 | ||
@@ -297,6 +315,16 @@ cipher_init(CipherContext *cc, const Cipher *cipher, | |||
297 | chachapoly_init(&cc->cp_ctx, key, keylen); | 315 | chachapoly_init(&cc->cp_ctx, key, keylen); |
298 | return; | 316 | return; |
299 | } | 317 | } |
318 | #ifndef WITH_OPENSSL | ||
319 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | ||
320 | aesctr_keysetup(&cc->ac_ctx, key, 8 * keylen, 8 * ivlen); | ||
321 | aesctr_ivsetup(&cc->ac_ctx, iv); | ||
322 | return; | ||
323 | } | ||
324 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | ||
325 | return; | ||
326 | fatal("unsupported cipher"); | ||
327 | #else | ||
300 | type = (*cipher->evptype)(); | 328 | type = (*cipher->evptype)(); |
301 | EVP_CIPHER_CTX_init(&cc->evp); | 329 | EVP_CIPHER_CTX_init(&cc->evp); |
302 | #ifdef SSH_OLD_EVP | 330 | #ifdef SSH_OLD_EVP |
@@ -339,6 +367,7 @@ cipher_init(CipherContext *cc, const Cipher *cipher, | |||
339 | free(junk); | 367 | free(junk); |
340 | free(discard); | 368 | free(discard); |
341 | } | 369 | } |
370 | #endif | ||
342 | } | 371 | } |
343 | 372 | ||
344 | /* | 373 | /* |
@@ -360,6 +389,20 @@ cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, | |||
360 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 389 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
361 | return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, | 390 | return chachapoly_crypt(&cc->cp_ctx, seqnr, dest, src, len, |
362 | aadlen, authlen, cc->encrypt); | 391 | aadlen, authlen, cc->encrypt); |
392 | #ifndef WITH_OPENSSL | ||
393 | if ((cc->cipher->flags & CFLAG_AESCTR) != 0) { | ||
394 | if (aadlen) | ||
395 | memcpy(dest, src, aadlen); | ||
396 | aesctr_encrypt_bytes(&cc->ac_ctx, src + aadlen, | ||
397 | dest + aadlen, len); | ||
398 | return 0; | ||
399 | } | ||
400 | if ((cc->cipher->flags & CFLAG_NONE) != 0) { | ||
401 | memcpy(dest, src, aadlen + len); | ||
402 | return 0; | ||
403 | } | ||
404 | fatal("unsupported cipher"); | ||
405 | #else | ||
363 | if (authlen) { | 406 | if (authlen) { |
364 | u_char lastiv[1]; | 407 | u_char lastiv[1]; |
365 | 408 | ||
@@ -400,6 +443,7 @@ cipher_crypt(CipherContext *cc, u_int seqnr, u_char *dest, const u_char *src, | |||
400 | fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); | 443 | fatal("%s: EVP_CTRL_GCM_GET_TAG", __func__); |
401 | } | 444 | } |
402 | return 0; | 445 | return 0; |
446 | #endif | ||
403 | } | 447 | } |
404 | 448 | ||
405 | /* Extract the packet length, including any decryption necessary beforehand */ | 449 | /* Extract the packet length, including any decryption necessary beforehand */ |
@@ -421,8 +465,12 @@ cipher_cleanup(CipherContext *cc) | |||
421 | { | 465 | { |
422 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 466 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
423 | explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); | 467 | explicit_bzero(&cc->cp_ctx, sizeof(cc->cp_ctx)); |
468 | else if ((cc->cipher->flags & CFLAG_AESCTR) != 0) | ||
469 | explicit_bzero(&cc->ac_ctx, sizeof(cc->ac_ctx)); | ||
470 | #ifdef WITH_OPENSSL | ||
424 | else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) | 471 | else if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0) |
425 | error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); | 472 | error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed"); |
473 | #endif | ||
426 | } | 474 | } |
427 | 475 | ||
428 | /* | 476 | /* |
@@ -455,14 +503,16 @@ int | |||
455 | cipher_get_keyiv_len(const CipherContext *cc) | 503 | cipher_get_keyiv_len(const CipherContext *cc) |
456 | { | 504 | { |
457 | const Cipher *c = cc->cipher; | 505 | const Cipher *c = cc->cipher; |
458 | int ivlen; | 506 | int ivlen = 0; |
459 | 507 | ||
460 | if (c->number == SSH_CIPHER_3DES) | 508 | if (c->number == SSH_CIPHER_3DES) |
461 | ivlen = 24; | 509 | ivlen = 24; |
462 | else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 510 | else if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
463 | ivlen = 0; | 511 | ivlen = 0; |
512 | #ifdef WITH_OPENSSL | ||
464 | else | 513 | else |
465 | ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); | 514 | ivlen = EVP_CIPHER_CTX_iv_length(&cc->evp); |
515 | #endif | ||
466 | return (ivlen); | 516 | return (ivlen); |
467 | } | 517 | } |
468 | 518 | ||
@@ -470,15 +520,20 @@ void | |||
470 | cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) | 520 | cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) |
471 | { | 521 | { |
472 | const Cipher *c = cc->cipher; | 522 | const Cipher *c = cc->cipher; |
523 | #ifdef WITH_OPENSSL | ||
473 | int evplen; | 524 | int evplen; |
525 | #endif | ||
474 | 526 | ||
475 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { | 527 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) { |
476 | if (len != 0) | 528 | if (len != 0) |
477 | fatal("%s: wrong iv length %d != %d", __func__, len, 0); | 529 | fatal("%s: wrong iv length %d != %d", __func__, len, 0); |
478 | return; | 530 | return; |
479 | } | 531 | } |
532 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | ||
533 | return; | ||
480 | 534 | ||
481 | switch (c->number) { | 535 | switch (c->number) { |
536 | #ifdef WITH_OPENSSL | ||
482 | case SSH_CIPHER_SSH2: | 537 | case SSH_CIPHER_SSH2: |
483 | case SSH_CIPHER_DES: | 538 | case SSH_CIPHER_DES: |
484 | case SSH_CIPHER_BLOWFISH: | 539 | case SSH_CIPHER_BLOWFISH: |
@@ -492,17 +547,20 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len) | |||
492 | if (c->evptype == evp_rijndael) | 547 | if (c->evptype == evp_rijndael) |
493 | ssh_rijndael_iv(&cc->evp, 0, iv, len); | 548 | ssh_rijndael_iv(&cc->evp, 0, iv, len); |
494 | else | 549 | else |
495 | #endif | 550 | #endif /* USE_BUILTIN_RIJNDAEL */ |
496 | #ifndef OPENSSL_HAVE_EVPCTR | 551 | #ifndef OPENSSL_HAVE_EVPCTR |
497 | if (c->evptype == evp_aes_128_ctr) | 552 | if (c->evptype == evp_aes_128_ctr) |
498 | ssh_aes_ctr_iv(&cc->evp, 0, iv, len); | 553 | ssh_aes_ctr_iv(&cc->evp, 0, iv, len); |
499 | else | 554 | else |
500 | #endif | 555 | #endif /* OPENSSL_HAVE_EVPCTR */ |
501 | memcpy(iv, cc->evp.iv, len); | 556 | memcpy(iv, cc->evp.iv, len); |
502 | break; | 557 | break; |
558 | #endif /* WITH_OPENSSL */ | ||
559 | #ifdef WITH_SSH1 | ||
503 | case SSH_CIPHER_3DES: | 560 | case SSH_CIPHER_3DES: |
504 | ssh1_3des_iv(&cc->evp, 0, iv, 24); | 561 | ssh1_3des_iv(&cc->evp, 0, iv, 24); |
505 | break; | 562 | break; |
563 | #endif /* WITH_SSH1 */ | ||
506 | default: | 564 | default: |
507 | fatal("%s: bad cipher %d", __func__, c->number); | 565 | fatal("%s: bad cipher %d", __func__, c->number); |
508 | } | 566 | } |
@@ -512,12 +570,17 @@ void | |||
512 | cipher_set_keyiv(CipherContext *cc, u_char *iv) | 570 | cipher_set_keyiv(CipherContext *cc, u_char *iv) |
513 | { | 571 | { |
514 | const Cipher *c = cc->cipher; | 572 | const Cipher *c = cc->cipher; |
573 | #ifdef WITH_OPENSSL | ||
515 | int evplen = 0; | 574 | int evplen = 0; |
575 | #endif | ||
516 | 576 | ||
517 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) | 577 | if ((cc->cipher->flags & CFLAG_CHACHAPOLY) != 0) |
518 | return; | 578 | return; |
579 | if ((cc->cipher->flags & CFLAG_NONE) != 0) | ||
580 | return; | ||
519 | 581 | ||
520 | switch (c->number) { | 582 | switch (c->number) { |
583 | #ifdef WITH_OPENSSL | ||
521 | case SSH_CIPHER_SSH2: | 584 | case SSH_CIPHER_SSH2: |
522 | case SSH_CIPHER_DES: | 585 | case SSH_CIPHER_DES: |
523 | case SSH_CIPHER_BLOWFISH: | 586 | case SSH_CIPHER_BLOWFISH: |
@@ -528,17 +591,20 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) | |||
528 | if (c->evptype == evp_rijndael) | 591 | if (c->evptype == evp_rijndael) |
529 | ssh_rijndael_iv(&cc->evp, 1, iv, evplen); | 592 | ssh_rijndael_iv(&cc->evp, 1, iv, evplen); |
530 | else | 593 | else |
531 | #endif | 594 | #endif /* USE_BUILTIN_RIJNDAEL */ |
532 | #ifndef OPENSSL_HAVE_EVPCTR | 595 | #ifndef OPENSSL_HAVE_EVPCTR |
533 | if (c->evptype == evp_aes_128_ctr) | 596 | if (c->evptype == evp_aes_128_ctr) |
534 | ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); | 597 | ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen); |
535 | else | 598 | else |
536 | #endif | 599 | #endif /* OPENSSL_HAVE_EVPCTR */ |
537 | memcpy(cc->evp.iv, iv, evplen); | 600 | memcpy(cc->evp.iv, iv, evplen); |
538 | break; | 601 | break; |
602 | #endif /* WITH_OPENSSL */ | ||
603 | #ifdef WITH_SSH1 | ||
539 | case SSH_CIPHER_3DES: | 604 | case SSH_CIPHER_3DES: |
540 | ssh1_3des_iv(&cc->evp, 1, iv, 24); | 605 | ssh1_3des_iv(&cc->evp, 1, iv, 24); |
541 | break; | 606 | break; |
607 | #endif /* WITH_SSH1 */ | ||
542 | default: | 608 | default: |
543 | fatal("%s: bad cipher %d", __func__, c->number); | 609 | fatal("%s: bad cipher %d", __func__, c->number); |
544 | } | 610 | } |
@@ -547,6 +613,7 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv) | |||
547 | int | 613 | int |
548 | cipher_get_keycontext(const CipherContext *cc, u_char *dat) | 614 | cipher_get_keycontext(const CipherContext *cc, u_char *dat) |
549 | { | 615 | { |
616 | #ifdef WITH_OPENSSL | ||
550 | const Cipher *c = cc->cipher; | 617 | const Cipher *c = cc->cipher; |
551 | int plen = 0; | 618 | int plen = 0; |
552 | 619 | ||
@@ -557,11 +624,15 @@ cipher_get_keycontext(const CipherContext *cc, u_char *dat) | |||
557 | memcpy(dat, EVP_X_STATE(cc->evp), plen); | 624 | memcpy(dat, EVP_X_STATE(cc->evp), plen); |
558 | } | 625 | } |
559 | return (plen); | 626 | return (plen); |
627 | #else | ||
628 | return (0); | ||
629 | #endif | ||
560 | } | 630 | } |
561 | 631 | ||
562 | void | 632 | void |
563 | cipher_set_keycontext(CipherContext *cc, u_char *dat) | 633 | cipher_set_keycontext(CipherContext *cc, u_char *dat) |
564 | { | 634 | { |
635 | #ifdef WITH_OPENSSL | ||
565 | const Cipher *c = cc->cipher; | 636 | const Cipher *c = cc->cipher; |
566 | int plen; | 637 | int plen; |
567 | 638 | ||
@@ -569,4 +640,5 @@ cipher_set_keycontext(CipherContext *cc, u_char *dat) | |||
569 | plen = EVP_X_STATE_LEN(cc->evp); | 640 | plen = EVP_X_STATE_LEN(cc->evp); |
570 | memcpy(EVP_X_STATE(cc->evp), dat, plen); | 641 | memcpy(EVP_X_STATE(cc->evp), dat, plen); |
571 | } | 642 | } |
643 | #endif | ||
572 | } | 644 | } |