diff options
-rw-r--r-- | ChangeLog | 6 | ||||
-rw-r--r-- | authfile.c | 26 | ||||
-rw-r--r-- | cipher.c | 47 | ||||
-rw-r--r-- | cipher.h | 29 | ||||
-rw-r--r-- | kex.c | 15 | ||||
-rw-r--r-- | kex.h | 4 | ||||
-rw-r--r-- | packet.c | 52 |
7 files changed, 109 insertions, 70 deletions
@@ -13,6 +13,10 @@ | |||
13 | [channels.h session.c ssh.c] | 13 | [channels.h session.c ssh.c] |
14 | increase the SSH v2 window size to 4 packets. comsumes a little | 14 | increase the SSH v2 window size to 4 packets. comsumes a little |
15 | bit more memory for slow receivers but increases througput. | 15 | bit more memory for slow receivers but increases througput. |
16 | - markus@cvs.openbsd.org 2002/02/14 23:41:01 | ||
17 | [authfile.c cipher.c cipher.h kex.c kex.h packet.c] | ||
18 | hide some more implementation details of cipher.[ch] and prepares for move | ||
19 | to EVP, ok deraadt@ | ||
16 | 20 | ||
17 | 20020218 | 21 | 20020218 |
18 | - (tim) newer config.guess from ftp://ftp.gnu.org/gnu/config/config.guess | 22 | - (tim) newer config.guess from ftp://ftp.gnu.org/gnu/config/config.guess |
@@ -7610,4 +7614,4 @@ | |||
7610 | - Wrote replacements for strlcpy and mkdtemp | 7614 | - Wrote replacements for strlcpy and mkdtemp |
7611 | - Released 1.0pre1 | 7615 | - Released 1.0pre1 |
7612 | 7616 | ||
7613 | $Id: ChangeLog,v 1.1857 2002/02/19 04:20:57 djm Exp $ | 7617 | $Id: ChangeLog,v 1.1858 2002/02/19 04:21:23 djm Exp $ |
diff --git a/authfile.c b/authfile.c index 69e0da03b..e35714e93 100644 --- a/authfile.c +++ b/authfile.c | |||
@@ -36,7 +36,7 @@ | |||
36 | */ | 36 | */ |
37 | 37 | ||
38 | #include "includes.h" | 38 | #include "includes.h" |
39 | RCSID("$OpenBSD: authfile.c,v 1.45 2001/12/29 21:56:01 stevesk Exp $"); | 39 | RCSID("$OpenBSD: authfile.c,v 1.46 2002/02/14 23:41:01 markus Exp $"); |
40 | 40 | ||
41 | #include <openssl/err.h> | 41 | #include <openssl/err.h> |
42 | #include <openssl/evp.h> | 42 | #include <openssl/evp.h> |
@@ -69,7 +69,7 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, | |||
69 | { | 69 | { |
70 | Buffer buffer, encrypted; | 70 | Buffer buffer, encrypted; |
71 | u_char buf[100], *cp; | 71 | u_char buf[100], *cp; |
72 | int fd, i; | 72 | int fd, i, cipher_num; |
73 | CipherContext ciphercontext; | 73 | CipherContext ciphercontext; |
74 | Cipher *cipher; | 74 | Cipher *cipher; |
75 | u_int32_t rand; | 75 | u_int32_t rand; |
@@ -78,11 +78,9 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, | |||
78 | * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting | 78 | * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting |
79 | * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. | 79 | * to another cipher; otherwise use SSH_AUTHFILE_CIPHER. |
80 | */ | 80 | */ |
81 | if (strcmp(passphrase, "") == 0) | 81 | cipher_num = (strcmp(passphrase, "") == 0) ? |
82 | cipher = cipher_by_number(SSH_CIPHER_NONE); | 82 | SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER; |
83 | else | 83 | if ((cipher = cipher_by_number(cipher_num)) == NULL) |
84 | cipher = cipher_by_number(SSH_AUTHFILE_CIPHER); | ||
85 | if (cipher == NULL) | ||
86 | fatal("save_private_key_rsa: bad cipher"); | 84 | fatal("save_private_key_rsa: bad cipher"); |
87 | 85 | ||
88 | /* This buffer is used to built the secret part of the private key. */ | 86 | /* This buffer is used to built the secret part of the private key. */ |
@@ -119,7 +117,7 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, | |||
119 | buffer_put_char(&encrypted, 0); | 117 | buffer_put_char(&encrypted, 0); |
120 | 118 | ||
121 | /* Store cipher type. */ | 119 | /* Store cipher type. */ |
122 | buffer_put_char(&encrypted, cipher->number); | 120 | buffer_put_char(&encrypted, cipher_num); |
123 | buffer_put_int(&encrypted, 0); /* For future extension */ | 121 | buffer_put_int(&encrypted, 0); /* For future extension */ |
124 | 122 | ||
125 | /* Store public key. This will be in plain text. */ | 123 | /* Store public key. This will be in plain text. */ |
@@ -131,9 +129,11 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase, | |||
131 | /* Allocate space for the private part of the key in the buffer. */ | 129 | /* Allocate space for the private part of the key in the buffer. */ |
132 | cp = buffer_append_space(&encrypted, buffer_len(&buffer)); | 130 | cp = buffer_append_space(&encrypted, buffer_len(&buffer)); |
133 | 131 | ||
134 | cipher_set_key_string(&ciphercontext, cipher, passphrase); | 132 | cipher_set_key_string(&ciphercontext, cipher, passphrase, |
135 | cipher_encrypt(&ciphercontext, cp, | 133 | CIPHER_ENCRYPT); |
134 | cipher_crypt(&ciphercontext, cp, | ||
136 | buffer_ptr(&buffer), buffer_len(&buffer)); | 135 | buffer_ptr(&buffer), buffer_len(&buffer)); |
136 | cipher_cleanup(&ciphercontext); | ||
137 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | 137 | memset(&ciphercontext, 0, sizeof(ciphercontext)); |
138 | 138 | ||
139 | /* Destroy temporary data. */ | 139 | /* Destroy temporary data. */ |
@@ -380,9 +380,11 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase, | |||
380 | cp = buffer_append_space(&decrypted, buffer_len(&buffer)); | 380 | cp = buffer_append_space(&decrypted, buffer_len(&buffer)); |
381 | 381 | ||
382 | /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ | 382 | /* Rest of the buffer is encrypted. Decrypt it using the passphrase. */ |
383 | cipher_set_key_string(&ciphercontext, cipher, passphrase); | 383 | cipher_set_key_string(&ciphercontext, cipher, passphrase, |
384 | cipher_decrypt(&ciphercontext, cp, | 384 | CIPHER_DECRYPT); |
385 | cipher_crypt(&ciphercontext, cp, | ||
385 | buffer_ptr(&buffer), buffer_len(&buffer)); | 386 | buffer_ptr(&buffer), buffer_len(&buffer)); |
387 | cipher_cleanup(&ciphercontext); | ||
386 | memset(&ciphercontext, 0, sizeof(ciphercontext)); | 388 | memset(&ciphercontext, 0, sizeof(ciphercontext)); |
387 | buffer_free(&buffer); | 389 | buffer_free(&buffer); |
388 | 390 | ||
@@ -35,7 +35,7 @@ | |||
35 | */ | 35 | */ |
36 | 36 | ||
37 | #include "includes.h" | 37 | #include "includes.h" |
38 | RCSID("$OpenBSD: cipher.c,v 1.50 2002/01/21 22:30:12 markus Exp $"); | 38 | RCSID("$OpenBSD: cipher.c,v 1.51 2002/02/14 23:41:01 markus Exp $"); |
39 | 39 | ||
40 | #include "xmalloc.h" | 40 | #include "xmalloc.h" |
41 | #include "log.h" | 41 | #include "log.h" |
@@ -43,6 +43,17 @@ RCSID("$OpenBSD: cipher.c,v 1.50 2002/01/21 22:30:12 markus Exp $"); | |||
43 | 43 | ||
44 | #include <openssl/md5.h> | 44 | #include <openssl/md5.h> |
45 | 45 | ||
46 | struct Cipher { | ||
47 | char *name; | ||
48 | int number; /* for ssh1 only */ | ||
49 | u_int block_size; | ||
50 | u_int key_len; | ||
51 | void (*setkey)(CipherContext *, const u_char *, u_int); | ||
52 | void (*setiv)(CipherContext *, const u_char *, u_int); | ||
53 | void (*encrypt)(CipherContext *, u_char *, const u_char *, u_int); | ||
54 | void (*decrypt)(CipherContext *, u_char *, const u_char *, u_int); | ||
55 | }; | ||
56 | |||
46 | /* no encryption */ | 57 | /* no encryption */ |
47 | static void | 58 | static void |
48 | none_setkey(CipherContext *cc, const u_char *key, u_int keylen) | 59 | none_setkey(CipherContext *cc, const u_char *key, u_int keylen) |
@@ -397,6 +408,18 @@ Cipher ciphers[] = { | |||
397 | 408 | ||
398 | /*--*/ | 409 | /*--*/ |
399 | 410 | ||
411 | u_int | ||
412 | cipher_blocksize(Cipher *c) | ||
413 | { | ||
414 | return (c->block_size); | ||
415 | } | ||
416 | |||
417 | u_int | ||
418 | cipher_keylen(Cipher *c) | ||
419 | { | ||
420 | return (c->key_len); | ||
421 | } | ||
422 | |||
400 | u_int | 423 | u_int |
401 | cipher_mask_ssh1(int client) | 424 | cipher_mask_ssh1(int client) |
402 | { | 425 | { |
@@ -479,8 +502,8 @@ cipher_name(int id) | |||
479 | } | 502 | } |
480 | 503 | ||
481 | void | 504 | void |
482 | cipher_init(CipherContext *cc, Cipher *cipher, | 505 | cipher_init(CipherContext *cc, Cipher *cipher, const u_char *key, |
483 | const u_char *key, u_int keylen, const u_char *iv, u_int ivlen) | 506 | u_int keylen, const u_char *iv, u_int ivlen, int encrypt) |
484 | { | 507 | { |
485 | if (keylen < cipher->key_len) | 508 | if (keylen < cipher->key_len) |
486 | fatal("cipher_init: key length %d is insufficient for %s.", | 509 | fatal("cipher_init: key length %d is insufficient for %s.", |
@@ -489,24 +512,26 @@ cipher_init(CipherContext *cc, Cipher *cipher, | |||
489 | fatal("cipher_init: iv length %d is insufficient for %s.", | 512 | fatal("cipher_init: iv length %d is insufficient for %s.", |
490 | ivlen, cipher->name); | 513 | ivlen, cipher->name); |
491 | cc->cipher = cipher; | 514 | cc->cipher = cipher; |
515 | cc->encrypt = (encrypt == CIPHER_ENCRYPT); | ||
492 | cipher->setkey(cc, key, keylen); | 516 | cipher->setkey(cc, key, keylen); |
493 | cipher->setiv(cc, iv, ivlen); | 517 | cipher->setiv(cc, iv, ivlen); |
494 | } | 518 | } |
495 | 519 | ||
496 | void | 520 | void |
497 | cipher_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) | 521 | cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) |
498 | { | 522 | { |
499 | if (len % cc->cipher->block_size) | 523 | if (len % cc->cipher->block_size) |
500 | fatal("cipher_encrypt: bad plaintext length %d", len); | 524 | fatal("cipher_encrypt: bad plaintext length %d", len); |
501 | cc->cipher->encrypt(cc, dest, src, len); | 525 | if (cc->encrypt) |
526 | cc->cipher->encrypt(cc, dest, src, len); | ||
527 | else | ||
528 | cc->cipher->decrypt(cc, dest, src, len); | ||
502 | } | 529 | } |
503 | 530 | ||
504 | void | 531 | void |
505 | cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) | 532 | cipher_cleanup(CipherContext *cc) |
506 | { | 533 | { |
507 | if (len % cc->cipher->block_size) | 534 | memset(cc, 0, sizeof(*cc)); |
508 | fatal("cipher_decrypt: bad ciphertext length %d", len); | ||
509 | cc->cipher->decrypt(cc, dest, src, len); | ||
510 | } | 535 | } |
511 | 536 | ||
512 | /* | 537 | /* |
@@ -516,7 +541,7 @@ cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len) | |||
516 | 541 | ||
517 | void | 542 | void |
518 | cipher_set_key_string(CipherContext *cc, Cipher *cipher, | 543 | cipher_set_key_string(CipherContext *cc, Cipher *cipher, |
519 | const char *passphrase) | 544 | const char *passphrase, int encrypt) |
520 | { | 545 | { |
521 | MD5_CTX md; | 546 | MD5_CTX md; |
522 | u_char digest[16]; | 547 | u_char digest[16]; |
@@ -525,7 +550,7 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher, | |||
525 | MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); | 550 | MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase)); |
526 | MD5_Final(digest, &md); | 551 | MD5_Final(digest, &md); |
527 | 552 | ||
528 | cipher_init(cc, cipher, digest, 16, NULL, 0); | 553 | cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt); |
529 | 554 | ||
530 | memset(digest, 0, sizeof(digest)); | 555 | memset(digest, 0, sizeof(digest)); |
531 | memset(&md, 0, sizeof(md)); | 556 | memset(&md, 0, sizeof(md)); |
@@ -32,7 +32,7 @@ | |||
32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 32 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
33 | */ | 33 | */ |
34 | 34 | ||
35 | /* RCSID("$OpenBSD: cipher.h,v 1.29 2001/08/23 11:31:59 markus Exp $"); */ | 35 | /* RCSID("$OpenBSD: cipher.h,v 1.30 2002/02/14 23:41:01 markus Exp $"); */ |
36 | 36 | ||
37 | #ifndef CIPHER_H | 37 | #ifndef CIPHER_H |
38 | #define CIPHER_H | 38 | #define CIPHER_H |
@@ -59,9 +59,13 @@ | |||
59 | #define SSH_CIPHER_RESERVED 7 | 59 | #define SSH_CIPHER_RESERVED 7 |
60 | #define SSH_CIPHER_MAX 31 | 60 | #define SSH_CIPHER_MAX 31 |
61 | 61 | ||
62 | #define CIPHER_ENCRYPT 1 | ||
63 | #define CIPHER_DECRYPT 0 | ||
64 | |||
62 | typedef struct Cipher Cipher; | 65 | typedef struct Cipher Cipher; |
63 | typedef struct CipherContext CipherContext; | 66 | typedef struct CipherContext CipherContext; |
64 | 67 | ||
68 | struct Cipher; | ||
65 | struct CipherContext { | 69 | struct CipherContext { |
66 | union { | 70 | union { |
67 | struct { | 71 | struct { |
@@ -91,18 +95,10 @@ struct CipherContext { | |||
91 | } rijndael; | 95 | } rijndael; |
92 | RC4_KEY rc4; | 96 | RC4_KEY rc4; |
93 | } u; | 97 | } u; |
98 | int plaintext; | ||
99 | int encrypt; | ||
94 | Cipher *cipher; | 100 | Cipher *cipher; |
95 | }; | 101 | }; |
96 | struct Cipher { | ||
97 | char *name; | ||
98 | int number; /* for ssh1 only */ | ||
99 | u_int block_size; | ||
100 | u_int key_len; | ||
101 | void (*setkey)(CipherContext *, const u_char *, u_int); | ||
102 | void (*setiv)(CipherContext *, const u_char *, u_int); | ||
103 | void (*encrypt)(CipherContext *, u_char *, const u_char *, u_int); | ||
104 | void (*decrypt)(CipherContext *, u_char *, const u_char *, u_int); | ||
105 | }; | ||
106 | 102 | ||
107 | u_int cipher_mask_ssh1(int); | 103 | u_int cipher_mask_ssh1(int); |
108 | Cipher *cipher_by_name(const char *); | 104 | Cipher *cipher_by_name(const char *); |
@@ -111,9 +107,10 @@ int cipher_number(const char *); | |||
111 | char *cipher_name(int); | 107 | char *cipher_name(int); |
112 | int ciphers_valid(const char *); | 108 | int ciphers_valid(const char *); |
113 | void cipher_init(CipherContext *, Cipher *, const u_char *, u_int, | 109 | void cipher_init(CipherContext *, Cipher *, const u_char *, u_int, |
114 | const u_char *, u_int); | 110 | const u_char *, u_int, int); |
115 | void cipher_encrypt(CipherContext *, u_char *, const u_char *, u_int); | 111 | void cipher_crypt(CipherContext *, u_char *, const u_char *, u_int); |
116 | void cipher_decrypt(CipherContext *, u_char *, const u_char *, u_int); | 112 | void cipher_cleanup(CipherContext *); |
117 | void cipher_set_key_string(CipherContext *, Cipher *, const char *); | 113 | void cipher_set_key_string(CipherContext *, Cipher *, const char *, int); |
118 | 114 | u_int cipher_blocksize(Cipher *); | |
115 | u_int cipher_keylen(Cipher *); | ||
119 | #endif /* CIPHER_H */ | 116 | #endif /* CIPHER_H */ |
@@ -23,7 +23,7 @@ | |||
23 | */ | 23 | */ |
24 | 24 | ||
25 | #include "includes.h" | 25 | #include "includes.h" |
26 | RCSID("$OpenBSD: kex.c,v 1.44 2002/02/11 16:10:15 markus Exp $"); | 26 | RCSID("$OpenBSD: kex.c,v 1.45 2002/02/14 23:41:01 markus Exp $"); |
27 | 27 | ||
28 | #include <openssl/crypto.h> | 28 | #include <openssl/crypto.h> |
29 | 29 | ||
@@ -232,13 +232,14 @@ choose_enc(Enc *enc, char *client, char *server) | |||
232 | char *name = match_list(client, server, NULL); | 232 | char *name = match_list(client, server, NULL); |
233 | if (name == NULL) | 233 | if (name == NULL) |
234 | fatal("no matching cipher found: client %s server %s", client, server); | 234 | fatal("no matching cipher found: client %s server %s", client, server); |
235 | enc->cipher = cipher_by_name(name); | 235 | if ((enc->cipher = cipher_by_name(name)) == NULL) |
236 | if (enc->cipher == NULL) | ||
237 | fatal("matching cipher is not supported: %s", name); | 236 | fatal("matching cipher is not supported: %s", name); |
238 | enc->name = name; | 237 | enc->name = name; |
239 | enc->enabled = 0; | 238 | enc->enabled = 0; |
240 | enc->iv = NULL; | 239 | enc->iv = NULL; |
241 | enc->key = NULL; | 240 | enc->key = NULL; |
241 | enc->key_len = cipher_keylen(enc->cipher); | ||
242 | enc->block_size = cipher_blocksize(enc->cipher); | ||
242 | } | 243 | } |
243 | static void | 244 | static void |
244 | choose_mac(Mac *mac, char *client, char *server) | 245 | choose_mac(Mac *mac, char *client, char *server) |
@@ -341,10 +342,10 @@ kex_choose_conf(Kex *kex) | |||
341 | need = 0; | 342 | need = 0; |
342 | for (mode = 0; mode < MODE_MAX; mode++) { | 343 | for (mode = 0; mode < MODE_MAX; mode++) { |
343 | newkeys = kex->newkeys[mode]; | 344 | newkeys = kex->newkeys[mode]; |
344 | if (need < newkeys->enc.cipher->key_len) | 345 | if (need < newkeys->enc.key_len) |
345 | need = newkeys->enc.cipher->key_len; | 346 | need = newkeys->enc.key_len; |
346 | if (need < newkeys->enc.cipher->block_size) | 347 | if (need < newkeys->enc.block_size) |
347 | need = newkeys->enc.cipher->block_size; | 348 | need = newkeys->enc.block_size; |
348 | if (need < newkeys->mac.key_len) | 349 | if (need < newkeys->mac.key_len) |
349 | need = newkeys->mac.key_len; | 350 | need = newkeys->mac.key_len; |
350 | } | 351 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kex.h,v 1.28 2001/12/28 15:06:00 markus Exp $ */ | 1 | /* $OpenBSD: kex.h,v 1.29 2002/02/14 23:41:01 markus Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
@@ -71,6 +71,8 @@ struct Enc { | |||
71 | char *name; | 71 | char *name; |
72 | Cipher *cipher; | 72 | Cipher *cipher; |
73 | int enabled; | 73 | int enabled; |
74 | u_int key_len; | ||
75 | u_int block_size; | ||
74 | u_char *key; | 76 | u_char *key; |
75 | u_char *iv; | 77 | u_char *iv; |
76 | }; | 78 | }; |
@@ -37,7 +37,7 @@ | |||
37 | */ | 37 | */ |
38 | 38 | ||
39 | #include "includes.h" | 39 | #include "includes.h" |
40 | RCSID("$OpenBSD: packet.c,v 1.87 2002/01/24 21:13:23 stevesk Exp $"); | 40 | RCSID("$OpenBSD: packet.c,v 1.88 2002/02/14 23:41:01 markus Exp $"); |
41 | 41 | ||
42 | #include "xmalloc.h" | 42 | #include "xmalloc.h" |
43 | #include "buffer.h" | 43 | #include "buffer.h" |
@@ -131,8 +131,8 @@ packet_set_connection(int fd_in, int fd_out) | |||
131 | fatal("packet_set_connection: cannot load cipher 'none'"); | 131 | fatal("packet_set_connection: cannot load cipher 'none'"); |
132 | connection_in = fd_in; | 132 | connection_in = fd_in; |
133 | connection_out = fd_out; | 133 | connection_out = fd_out; |
134 | cipher_init(&send_context, none, "", 0, NULL, 0); | 134 | cipher_init(&send_context, none, "", 0, NULL, 0, CIPHER_ENCRYPT); |
135 | cipher_init(&receive_context, none, "", 0, NULL, 0); | 135 | cipher_init(&receive_context, none, "", 0, NULL, 0, CIPHER_DECRYPT); |
136 | newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; | 136 | newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL; |
137 | if (!initialized) { | 137 | if (!initialized) { |
138 | initialized = 1; | 138 | initialized = 1; |
@@ -241,6 +241,8 @@ packet_close(void) | |||
241 | buffer_free(&compression_buffer); | 241 | buffer_free(&compression_buffer); |
242 | buffer_compress_uninit(); | 242 | buffer_compress_uninit(); |
243 | } | 243 | } |
244 | cipher_cleanup(&send_context); | ||
245 | cipher_cleanup(&receive_context); | ||
244 | } | 246 | } |
245 | 247 | ||
246 | /* Sets remote side protocol flags. */ | 248 | /* Sets remote side protocol flags. */ |
@@ -298,8 +300,8 @@ packet_set_encryption_key(const u_char *key, u_int keylen, | |||
298 | fatal("packet_set_encryption_key: unknown cipher number %d", number); | 300 | fatal("packet_set_encryption_key: unknown cipher number %d", number); |
299 | if (keylen < 20) | 301 | if (keylen < 20) |
300 | fatal("packet_set_encryption_key: keylen too small: %d", keylen); | 302 | fatal("packet_set_encryption_key: keylen too small: %d", keylen); |
301 | cipher_init(&receive_context, cipher, key, keylen, NULL, 0); | 303 | cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT); |
302 | cipher_init(&send_context, cipher, key, keylen, NULL, 0); | 304 | cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT); |
303 | } | 305 | } |
304 | 306 | ||
305 | /* Start constructing a packet to send. */ | 307 | /* Start constructing a packet to send. */ |
@@ -388,7 +390,7 @@ packet_send1(void) | |||
388 | 390 | ||
389 | /* Insert padding. Initialized to zero in packet_start1() */ | 391 | /* Insert padding. Initialized to zero in packet_start1() */ |
390 | padding = 8 - len % 8; | 392 | padding = 8 - len % 8; |
391 | if (send_context.cipher->number != SSH_CIPHER_NONE) { | 393 | if (!send_context.plaintext) { |
392 | cp = buffer_ptr(&outgoing_packet); | 394 | cp = buffer_ptr(&outgoing_packet); |
393 | for (i = 0; i < padding; i++) { | 395 | for (i = 0; i < padding; i++) { |
394 | if (i % 4 == 0) | 396 | if (i % 4 == 0) |
@@ -414,7 +416,7 @@ packet_send1(void) | |||
414 | PUT_32BIT(buf, len); | 416 | PUT_32BIT(buf, len); |
415 | buffer_append(&output, buf, 4); | 417 | buffer_append(&output, buf, 4); |
416 | cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); | 418 | cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
417 | cipher_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), | 419 | cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), |
418 | buffer_len(&outgoing_packet)); | 420 | buffer_len(&outgoing_packet)); |
419 | 421 | ||
420 | #ifdef PACKET_DEBUG | 422 | #ifdef PACKET_DEBUG |
@@ -438,14 +440,20 @@ set_newkeys(int mode) | |||
438 | Mac *mac; | 440 | Mac *mac; |
439 | Comp *comp; | 441 | Comp *comp; |
440 | CipherContext *cc; | 442 | CipherContext *cc; |
443 | int encrypt; | ||
441 | 444 | ||
442 | debug("newkeys: mode %d", mode); | 445 | debug("newkeys: mode %d", mode); |
443 | 446 | ||
444 | cc = (mode == MODE_OUT) ? &send_context : &receive_context; | 447 | if (mode == MODE_OUT) { |
448 | cc = &send_context; | ||
449 | encrypt = CIPHER_ENCRYPT; | ||
450 | } else { | ||
451 | cc = &receive_context; | ||
452 | encrypt = CIPHER_DECRYPT; | ||
453 | } | ||
445 | if (newkeys[mode] != NULL) { | 454 | if (newkeys[mode] != NULL) { |
446 | debug("newkeys: rekeying"); | 455 | debug("newkeys: rekeying"); |
447 | /* todo: free old keys, reset compression/cipher-ctxt; */ | 456 | cipher_cleanup(cc); |
448 | memset(cc, 0, sizeof(*cc)); | ||
449 | enc = &newkeys[mode]->enc; | 457 | enc = &newkeys[mode]->enc; |
450 | mac = &newkeys[mode]->mac; | 458 | mac = &newkeys[mode]->mac; |
451 | comp = &newkeys[mode]->comp; | 459 | comp = &newkeys[mode]->comp; |
@@ -467,10 +475,10 @@ set_newkeys(int mode) | |||
467 | if (mac->md != NULL) | 475 | if (mac->md != NULL) |
468 | mac->enabled = 1; | 476 | mac->enabled = 1; |
469 | DBG(debug("cipher_init_context: %d", mode)); | 477 | DBG(debug("cipher_init_context: %d", mode)); |
470 | cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len, | 478 | cipher_init(cc, enc->cipher, enc->key, enc->key_len, |
471 | enc->iv, enc->cipher->block_size); | 479 | enc->iv, enc->block_size, encrypt); |
472 | memset(enc->iv, 0, enc->cipher->block_size); | 480 | memset(enc->iv, 0, enc->block_size); |
473 | memset(enc->key, 0, enc->cipher->key_len); | 481 | memset(enc->key, 0, enc->key_len); |
474 | if (comp->type != 0 && comp->enabled == 0) { | 482 | if (comp->type != 0 && comp->enabled == 0) { |
475 | packet_init_compression(); | 483 | packet_init_compression(); |
476 | if (mode == MODE_OUT) | 484 | if (mode == MODE_OUT) |
@@ -504,7 +512,7 @@ packet_send2(void) | |||
504 | mac = &newkeys[MODE_OUT]->mac; | 512 | mac = &newkeys[MODE_OUT]->mac; |
505 | comp = &newkeys[MODE_OUT]->comp; | 513 | comp = &newkeys[MODE_OUT]->comp; |
506 | } | 514 | } |
507 | block_size = enc ? enc->cipher->block_size : 8; | 515 | block_size = enc ? enc->block_size : 8; |
508 | 516 | ||
509 | ucp = buffer_ptr(&outgoing_packet); | 517 | ucp = buffer_ptr(&outgoing_packet); |
510 | type = ucp[5]; | 518 | type = ucp[5]; |
@@ -548,7 +556,7 @@ packet_send2(void) | |||
548 | extra_pad = 0; | 556 | extra_pad = 0; |
549 | } | 557 | } |
550 | cp = buffer_append_space(&outgoing_packet, padlen); | 558 | cp = buffer_append_space(&outgoing_packet, padlen); |
551 | if (enc && enc->cipher->number != SSH_CIPHER_NONE) { | 559 | if (enc && !send_context.plaintext) { |
552 | /* random padding */ | 560 | /* random padding */ |
553 | for (i = 0; i < padlen; i++) { | 561 | for (i = 0; i < padlen; i++) { |
554 | if (i % 4 == 0) | 562 | if (i % 4 == 0) |
@@ -576,7 +584,7 @@ packet_send2(void) | |||
576 | } | 584 | } |
577 | /* encrypt packet and append to output buffer. */ | 585 | /* encrypt packet and append to output buffer. */ |
578 | cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); | 586 | cp = buffer_append_space(&output, buffer_len(&outgoing_packet)); |
579 | cipher_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet), | 587 | cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet), |
580 | buffer_len(&outgoing_packet)); | 588 | buffer_len(&outgoing_packet)); |
581 | /* append unencrypted MAC */ | 589 | /* append unencrypted MAC */ |
582 | if (mac && mac->enabled) | 590 | if (mac && mac->enabled) |
@@ -729,14 +737,14 @@ packet_read_poll1(void) | |||
729 | * (C)1998 CORE-SDI, Buenos Aires Argentina | 737 | * (C)1998 CORE-SDI, Buenos Aires Argentina |
730 | * Ariel Futoransky(futo@core-sdi.com) | 738 | * Ariel Futoransky(futo@core-sdi.com) |
731 | */ | 739 | */ |
732 | if (receive_context.cipher->number != SSH_CIPHER_NONE && | 740 | if (!receive_context.plaintext && |
733 | detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED) | 741 | detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED) |
734 | packet_disconnect("crc32 compensation attack: network attack detected"); | 742 | packet_disconnect("crc32 compensation attack: network attack detected"); |
735 | 743 | ||
736 | /* Decrypt data to incoming_packet. */ | 744 | /* Decrypt data to incoming_packet. */ |
737 | buffer_clear(&incoming_packet); | 745 | buffer_clear(&incoming_packet); |
738 | cp = buffer_append_space(&incoming_packet, padded_len); | 746 | cp = buffer_append_space(&incoming_packet, padded_len); |
739 | cipher_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len); | 747 | cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len); |
740 | 748 | ||
741 | buffer_consume(&input, padded_len); | 749 | buffer_consume(&input, padded_len); |
742 | 750 | ||
@@ -793,7 +801,7 @@ packet_read_poll2(u_int32_t *seqnr_p) | |||
793 | comp = &newkeys[MODE_IN]->comp; | 801 | comp = &newkeys[MODE_IN]->comp; |
794 | } | 802 | } |
795 | maclen = mac && mac->enabled ? mac->mac_len : 0; | 803 | maclen = mac && mac->enabled ? mac->mac_len : 0; |
796 | block_size = enc ? enc->cipher->block_size : 8; | 804 | block_size = enc ? enc->block_size : 8; |
797 | 805 | ||
798 | if (packet_length == 0) { | 806 | if (packet_length == 0) { |
799 | /* | 807 | /* |
@@ -804,7 +812,7 @@ packet_read_poll2(u_int32_t *seqnr_p) | |||
804 | return SSH_MSG_NONE; | 812 | return SSH_MSG_NONE; |
805 | buffer_clear(&incoming_packet); | 813 | buffer_clear(&incoming_packet); |
806 | cp = buffer_append_space(&incoming_packet, block_size); | 814 | cp = buffer_append_space(&incoming_packet, block_size); |
807 | cipher_decrypt(&receive_context, cp, buffer_ptr(&input), | 815 | cipher_crypt(&receive_context, cp, buffer_ptr(&input), |
808 | block_size); | 816 | block_size); |
809 | ucp = buffer_ptr(&incoming_packet); | 817 | ucp = buffer_ptr(&incoming_packet); |
810 | packet_length = GET_32BIT(ucp); | 818 | packet_length = GET_32BIT(ucp); |
@@ -833,7 +841,7 @@ packet_read_poll2(u_int32_t *seqnr_p) | |||
833 | buffer_dump(&input); | 841 | buffer_dump(&input); |
834 | #endif | 842 | #endif |
835 | cp = buffer_append_space(&incoming_packet, need); | 843 | cp = buffer_append_space(&incoming_packet, need); |
836 | cipher_decrypt(&receive_context, cp, buffer_ptr(&input), need); | 844 | cipher_crypt(&receive_context, cp, buffer_ptr(&input), need); |
837 | buffer_consume(&input, need); | 845 | buffer_consume(&input, need); |
838 | /* | 846 | /* |
839 | * compute MAC over seqnr and packet, | 847 | * compute MAC over seqnr and packet, |