]> andersk Git - openssh.git/commitdiff
- markus@cvs.openbsd.org 2002/02/14 23:41:01
authordjm <djm>
Tue, 19 Feb 2002 04:21:23 +0000 (04:21 +0000)
committerdjm <djm>
Tue, 19 Feb 2002 04:21:23 +0000 (04:21 +0000)
     [authfile.c cipher.c cipher.h kex.c kex.h packet.c]
     hide some more implementation details of cipher.[ch] and prepares for move
     to EVP, ok deraadt@

ChangeLog
authfile.c
cipher.c
cipher.h
kex.c
kex.h
packet.c

index 327aed9243bc4e9de298d49074140e4e15a40db0..96633c69b66381c89eb6e221942bb2a5fc3ecb5d 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
      [channels.h session.c ssh.c]
      increase the SSH v2 window size to 4 packets. comsumes a little
      bit more memory for slow receivers but increases througput.
+   - markus@cvs.openbsd.org 2002/02/14 23:41:01
+     [authfile.c cipher.c cipher.h kex.c kex.h packet.c]
+     hide some more implementation details of cipher.[ch] and prepares for move
+     to EVP, ok deraadt@
 
 20020218
  - (tim) newer config.guess from ftp://ftp.gnu.org/gnu/config/config.guess
index 69e0da03b7b5fac2a8b2b66067ae9fc82730aba3..e35714e93be7cf9ced5242081e43cb127bb7f8ae 100644 (file)
@@ -36,7 +36,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: authfile.c,v 1.45 2001/12/29 21:56:01 stevesk Exp $");
+RCSID("$OpenBSD: authfile.c,v 1.46 2002/02/14 23:41:01 markus Exp $");
 
 #include <openssl/err.h>
 #include <openssl/evp.h>
@@ -69,7 +69,7 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
 {
        Buffer buffer, encrypted;
        u_char buf[100], *cp;
-       int fd, i;
+       int fd, i, cipher_num;
        CipherContext ciphercontext;
        Cipher *cipher;
        u_int32_t rand;
@@ -78,11 +78,9 @@ key_save_private_rsa1(Key *key, const char *filename, const char *passphrase,
         * If the passphrase is empty, use SSH_CIPHER_NONE to ease converting
         * to another cipher; otherwise use SSH_AUTHFILE_CIPHER.
         */
-       if (strcmp(passphrase, "") == 0)
-               cipher = cipher_by_number(SSH_CIPHER_NONE);
-       else
-               cipher = cipher_by_number(SSH_AUTHFILE_CIPHER);
-       if (cipher == NULL)
+       cipher_num = (strcmp(passphrase, "") == 0) ?
+           SSH_CIPHER_NONE : SSH_AUTHFILE_CIPHER;
+       if ((cipher = cipher_by_number(cipher_num)) == NULL)
                fatal("save_private_key_rsa: bad cipher");
 
        /* 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,
        buffer_put_char(&encrypted, 0);
 
        /* Store cipher type. */
-       buffer_put_char(&encrypted, cipher->number);
+       buffer_put_char(&encrypted, cipher_num);
        buffer_put_int(&encrypted, 0);  /* For future extension */
 
        /* 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,
        /* Allocate space for the private part of the key in the buffer. */
        cp = buffer_append_space(&encrypted, buffer_len(&buffer));
 
-       cipher_set_key_string(&ciphercontext, cipher, passphrase);
-       cipher_encrypt(&ciphercontext, cp,
+       cipher_set_key_string(&ciphercontext, cipher, passphrase,
+           CIPHER_ENCRYPT);
+       cipher_crypt(&ciphercontext, cp,
            buffer_ptr(&buffer), buffer_len(&buffer));
+       cipher_cleanup(&ciphercontext);
        memset(&ciphercontext, 0, sizeof(ciphercontext));
 
        /* Destroy temporary data. */
@@ -380,9 +380,11 @@ key_load_private_rsa1(int fd, const char *filename, const char *passphrase,
        cp = buffer_append_space(&decrypted, buffer_len(&buffer));
 
        /* Rest of the buffer is encrypted.  Decrypt it using the passphrase. */
-       cipher_set_key_string(&ciphercontext, cipher, passphrase);
-       cipher_decrypt(&ciphercontext, cp,
+       cipher_set_key_string(&ciphercontext, cipher, passphrase,
+           CIPHER_DECRYPT);
+       cipher_crypt(&ciphercontext, cp,
            buffer_ptr(&buffer), buffer_len(&buffer));
+       cipher_cleanup(&ciphercontext);
        memset(&ciphercontext, 0, sizeof(ciphercontext));
        buffer_free(&buffer);
 
index 58b0e8aa78ed087dbe220d88f8986ea2f673ba3a..c31696cee20b03b26472c3be45715c7330d03221 100644 (file)
--- a/cipher.c
+++ b/cipher.c
@@ -35,7 +35,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher.c,v 1.50 2002/01/21 22:30:12 markus Exp $");
+RCSID("$OpenBSD: cipher.c,v 1.51 2002/02/14 23:41:01 markus Exp $");
 
 #include "xmalloc.h"
 #include "log.h"
@@ -43,6 +43,17 @@ RCSID("$OpenBSD: cipher.c,v 1.50 2002/01/21 22:30:12 markus Exp $");
 
 #include <openssl/md5.h>
 
+struct Cipher {
+       char    *name;
+       int     number;         /* for ssh1 only */
+       u_int   block_size;
+       u_int   key_len;
+       void    (*setkey)(CipherContext *, const u_char *, u_int);
+       void    (*setiv)(CipherContext *, const u_char *, u_int);
+       void    (*encrypt)(CipherContext *, u_char *, const u_char *, u_int);
+       void    (*decrypt)(CipherContext *, u_char *, const u_char *, u_int);
+};
+
 /* no encryption */
 static void
 none_setkey(CipherContext *cc, const u_char *key, u_int keylen)
@@ -397,6 +408,18 @@ Cipher ciphers[] = {
 
 /*--*/
 
+u_int   
+cipher_blocksize(Cipher *c)
+{
+       return (c->block_size);
+}
+
+u_int   
+cipher_keylen(Cipher *c)
+{
+       return (c->key_len);
+}
+
 u_int
 cipher_mask_ssh1(int client)
 {
@@ -479,8 +502,8 @@ cipher_name(int id)
 }
 
 void
-cipher_init(CipherContext *cc, Cipher *cipher,
-    const u_char *key, u_int keylen, const u_char *iv, u_int ivlen)
+cipher_init(CipherContext *cc, Cipher *cipher, const u_char *key,
+     u_int keylen, const u_char *iv, u_int ivlen, int encrypt)
 {
        if (keylen < cipher->key_len)
                fatal("cipher_init: key length %d is insufficient for %s.",
@@ -489,24 +512,26 @@ cipher_init(CipherContext *cc, Cipher *cipher,
                fatal("cipher_init: iv length %d is insufficient for %s.",
                    ivlen, cipher->name);
        cc->cipher = cipher;
+       cc->encrypt = (encrypt == CIPHER_ENCRYPT);
        cipher->setkey(cc, key, keylen);
        cipher->setiv(cc, iv, ivlen);
 }
 
 void
-cipher_encrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
+cipher_crypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
 {
        if (len % cc->cipher->block_size)
                fatal("cipher_encrypt: bad plaintext length %d", len);
-       cc->cipher->encrypt(cc, dest, src, len);
+       if (cc->encrypt)
+               cc->cipher->encrypt(cc, dest, src, len);
+       else
+               cc->cipher->decrypt(cc, dest, src, len);
 }
 
 void
-cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
+cipher_cleanup(CipherContext *cc)
 {
-       if (len % cc->cipher->block_size)
-               fatal("cipher_decrypt: bad ciphertext length %d", len);
-       cc->cipher->decrypt(cc, dest, src, len);
+       memset(cc, 0, sizeof(*cc));
 }
 
 /*
@@ -516,7 +541,7 @@ cipher_decrypt(CipherContext *cc, u_char *dest, const u_char *src, u_int len)
 
 void
 cipher_set_key_string(CipherContext *cc, Cipher *cipher,
-    const char *passphrase)
+    const char *passphrase, int encrypt)
 {
        MD5_CTX md;
        u_char digest[16];
@@ -525,7 +550,7 @@ cipher_set_key_string(CipherContext *cc, Cipher *cipher,
        MD5_Update(&md, (const u_char *)passphrase, strlen(passphrase));
        MD5_Final(digest, &md);
 
-       cipher_init(cc, cipher, digest, 16, NULL, 0);
+       cipher_init(cc, cipher, digest, 16, NULL, 0, encrypt);
 
        memset(digest, 0, sizeof(digest));
        memset(&md, 0, sizeof(md));
index 4533f5e4c20fd40c6b58ade84f33b089cba0a0a1..0c412b47f956733520f2176f3a71861c0a3ff57f 100644 (file)
--- a/cipher.h
+++ b/cipher.h
@@ -32,7 +32,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* RCSID("$OpenBSD: cipher.h,v 1.29 2001/08/23 11:31:59 markus Exp $"); */
+/* RCSID("$OpenBSD: cipher.h,v 1.30 2002/02/14 23:41:01 markus Exp $"); */
 
 #ifndef CIPHER_H
 #define CIPHER_H
 #define SSH_CIPHER_RESERVED    7
 #define SSH_CIPHER_MAX         31
 
+#define CIPHER_ENCRYPT         1
+#define CIPHER_DECRYPT         0
+
 typedef struct Cipher Cipher;
 typedef struct CipherContext CipherContext;
 
+struct Cipher;
 struct CipherContext {
        union {
                struct {
@@ -91,18 +95,10 @@ struct CipherContext {
                } rijndael;
                RC4_KEY rc4;
        }       u;
+       int     plaintext;
+       int     encrypt;
        Cipher *cipher;
 };
-struct Cipher {
-       char    *name;
-       int     number;         /* for ssh1 only */
-       u_int   block_size;
-       u_int   key_len;
-       void    (*setkey)(CipherContext *, const u_char *, u_int);
-       void    (*setiv)(CipherContext *, const u_char *, u_int);
-       void    (*encrypt)(CipherContext *, u_char *, const u_char *, u_int);
-       void    (*decrypt)(CipherContext *, u_char *, const u_char *, u_int);
-};
 
 u_int   cipher_mask_ssh1(int);
 Cipher *cipher_by_name(const char *);
@@ -111,9 +107,10 @@ int         cipher_number(const char *);
 char   *cipher_name(int);
 int     ciphers_valid(const char *);
 void    cipher_init(CipherContext *, Cipher *, const u_char *, u_int,
-    const u_char *, u_int);
-void    cipher_encrypt(CipherContext *, u_char *, const u_char *, u_int);
-void    cipher_decrypt(CipherContext *, u_char *, const u_char *, u_int);
-void    cipher_set_key_string(CipherContext *, Cipher *, const char *);
-
+    const u_char *, u_int, int);
+void    cipher_crypt(CipherContext *, u_char *, const u_char *, u_int);
+void    cipher_cleanup(CipherContext *);
+void    cipher_set_key_string(CipherContext *, Cipher *, const char *, int);
+u_int   cipher_blocksize(Cipher *);
+u_int   cipher_keylen(Cipher *);
 #endif                         /* CIPHER_H */
diff --git a/kex.c b/kex.c
index 02c9780ad1d1728ac900aa68ef796169c771bd5c..e9f944b05ba92eff4b12e17ddeadfe2ffffd3034 100644 (file)
--- a/kex.c
+++ b/kex.c
@@ -23,7 +23,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: kex.c,v 1.44 2002/02/11 16:10:15 markus Exp $");
+RCSID("$OpenBSD: kex.c,v 1.45 2002/02/14 23:41:01 markus Exp $");
 
 #include <openssl/crypto.h>
 
@@ -232,13 +232,14 @@ choose_enc(Enc *enc, char *client, char *server)
        char *name = match_list(client, server, NULL);
        if (name == NULL)
                fatal("no matching cipher found: client %s server %s", client, server);
-       enc->cipher = cipher_by_name(name);
-       if (enc->cipher == NULL)
+       if ((enc->cipher = cipher_by_name(name)) == NULL)
                fatal("matching cipher is not supported: %s", name);
        enc->name = name;
        enc->enabled = 0;
        enc->iv = NULL;
        enc->key = NULL;
+       enc->key_len = cipher_keylen(enc->cipher);
+       enc->block_size = cipher_blocksize(enc->cipher);
 }
 static void
 choose_mac(Mac *mac, char *client, char *server)
@@ -341,10 +342,10 @@ kex_choose_conf(Kex *kex)
        need = 0;
        for (mode = 0; mode < MODE_MAX; mode++) {
                newkeys = kex->newkeys[mode];
-               if (need < newkeys->enc.cipher->key_len)
-                       need = newkeys->enc.cipher->key_len;
-               if (need < newkeys->enc.cipher->block_size)
-                       need = newkeys->enc.cipher->block_size;
+               if (need < newkeys->enc.key_len)
+                       need = newkeys->enc.key_len;
+               if (need < newkeys->enc.block_size)
+                       need = newkeys->enc.block_size;
                if (need < newkeys->mac.key_len)
                        need = newkeys->mac.key_len;
        }
diff --git a/kex.h b/kex.h
index 7bd6bc2159bf007e24417e00cef6ed2fede14ae0..755bf332aa40b52ddd26abc31a82e626a4a63a58 100644 (file)
--- a/kex.h
+++ b/kex.h
@@ -1,4 +1,4 @@
-/*     $OpenBSD: kex.h,v 1.28 2001/12/28 15:06:00 markus Exp $ */
+/*     $OpenBSD: kex.h,v 1.29 2002/02/14 23:41:01 markus Exp $ */
 
 /*
  * Copyright (c) 2000, 2001 Markus Friedl.  All rights reserved.
@@ -71,6 +71,8 @@ struct Enc {
        char    *name;
        Cipher  *cipher;
        int     enabled;
+       u_int   key_len;
+       u_int   block_size;
        u_char  *key;
        u_char  *iv;
 };
index e334c4b6933a2d1caf6d97522d59adb1cba7d21e..794659b8af6ab728d258c7f5e8d55fcb5db87eaa 100644 (file)
--- a/packet.c
+++ b/packet.c
@@ -37,7 +37,7 @@
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: packet.c,v 1.87 2002/01/24 21:13:23 stevesk Exp $");
+RCSID("$OpenBSD: packet.c,v 1.88 2002/02/14 23:41:01 markus Exp $");
 
 #include "xmalloc.h"
 #include "buffer.h"
@@ -131,8 +131,8 @@ packet_set_connection(int fd_in, int fd_out)
                fatal("packet_set_connection: cannot load cipher 'none'");
        connection_in = fd_in;
        connection_out = fd_out;
-       cipher_init(&send_context, none, "", 0, NULL, 0);
-       cipher_init(&receive_context, none, "", 0, NULL, 0);
+       cipher_init(&send_context, none, "", 0, NULL, 0, CIPHER_ENCRYPT);
+       cipher_init(&receive_context, none, "", 0, NULL, 0, CIPHER_DECRYPT);
        newkeys[MODE_IN] = newkeys[MODE_OUT] = NULL;
        if (!initialized) {
                initialized = 1;
@@ -241,6 +241,8 @@ packet_close(void)
                buffer_free(&compression_buffer);
                buffer_compress_uninit();
        }
+       cipher_cleanup(&send_context);
+       cipher_cleanup(&receive_context);
 }
 
 /* Sets remote side protocol flags. */
@@ -298,8 +300,8 @@ packet_set_encryption_key(const u_char *key, u_int keylen,
                fatal("packet_set_encryption_key: unknown cipher number %d", number);
        if (keylen < 20)
                fatal("packet_set_encryption_key: keylen too small: %d", keylen);
-       cipher_init(&receive_context, cipher, key, keylen, NULL, 0);
-       cipher_init(&send_context, cipher, key, keylen, NULL, 0);
+       cipher_init(&send_context, cipher, key, keylen, NULL, 0, CIPHER_ENCRYPT);
+       cipher_init(&receive_context, cipher, key, keylen, NULL, 0, CIPHER_DECRYPT);
 }
 
 /* Start constructing a packet to send. */
@@ -388,7 +390,7 @@ packet_send1(void)
 
        /* Insert padding. Initialized to zero in packet_start1() */
        padding = 8 - len % 8;
-       if (send_context.cipher->number != SSH_CIPHER_NONE) {
+       if (!send_context.plaintext) {
                cp = buffer_ptr(&outgoing_packet);
                for (i = 0; i < padding; i++) {
                        if (i % 4 == 0)
@@ -414,7 +416,7 @@ packet_send1(void)
        PUT_32BIT(buf, len);
        buffer_append(&output, buf, 4);
        cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
-       cipher_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
+       cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
            buffer_len(&outgoing_packet));
 
 #ifdef PACKET_DEBUG
@@ -438,14 +440,20 @@ set_newkeys(int mode)
        Mac *mac;
        Comp *comp;
        CipherContext *cc;
+       int encrypt;
 
        debug("newkeys: mode %d", mode);
 
-       cc = (mode == MODE_OUT) ? &send_context : &receive_context;
+       if (mode == MODE_OUT) {
+               cc = &send_context;
+               encrypt = CIPHER_ENCRYPT;
+       } else {
+               cc = &receive_context;
+               encrypt = CIPHER_DECRYPT;
+       }
        if (newkeys[mode] != NULL) {
                debug("newkeys: rekeying");
-               /* todo: free old keys, reset compression/cipher-ctxt; */
-               memset(cc, 0, sizeof(*cc));
+               cipher_cleanup(cc);
                enc  = &newkeys[mode]->enc;
                mac  = &newkeys[mode]->mac;
                comp = &newkeys[mode]->comp;
@@ -467,10 +475,10 @@ set_newkeys(int mode)
        if (mac->md != NULL)
                mac->enabled = 1;
        DBG(debug("cipher_init_context: %d", mode));
-       cipher_init(cc, enc->cipher, enc->key, enc->cipher->key_len,
-           enc->iv, enc->cipher->block_size);
-       memset(enc->iv,  0, enc->cipher->block_size);
-       memset(enc->key, 0, enc->cipher->key_len);
+       cipher_init(cc, enc->cipher, enc->key, enc->key_len,
+           enc->iv, enc->block_size, encrypt);
+       memset(enc->iv,  0, enc->block_size);
+       memset(enc->key, 0, enc->key_len);
        if (comp->type != 0 && comp->enabled == 0) {
                packet_init_compression();
                if (mode == MODE_OUT)
@@ -504,7 +512,7 @@ packet_send2(void)
                mac  = &newkeys[MODE_OUT]->mac;
                comp = &newkeys[MODE_OUT]->comp;
        }
-       block_size = enc ? enc->cipher->block_size : 8;
+       block_size = enc ? enc->block_size : 8;
 
        ucp = buffer_ptr(&outgoing_packet);
        type = ucp[5];
@@ -548,7 +556,7 @@ packet_send2(void)
                extra_pad = 0;
        }
        cp = buffer_append_space(&outgoing_packet, padlen);
-       if (enc && enc->cipher->number != SSH_CIPHER_NONE) {
+       if (enc && !send_context.plaintext) {
                /* random padding */
                for (i = 0; i < padlen; i++) {
                        if (i % 4 == 0)
@@ -576,7 +584,7 @@ packet_send2(void)
        }
        /* encrypt packet and append to output buffer. */
        cp = buffer_append_space(&output, buffer_len(&outgoing_packet));
-       cipher_encrypt(&send_context, cp, buffer_ptr(&outgoing_packet),
+       cipher_crypt(&send_context, cp, buffer_ptr(&outgoing_packet),
            buffer_len(&outgoing_packet));
        /* append unencrypted MAC */
        if (mac && mac->enabled)
@@ -729,14 +737,14 @@ packet_read_poll1(void)
         * (C)1998 CORE-SDI, Buenos Aires Argentina
         * Ariel Futoransky(futo@core-sdi.com)
         */
-       if (receive_context.cipher->number != SSH_CIPHER_NONE &&
+       if (!receive_context.plaintext &&
            detect_attack(buffer_ptr(&input), padded_len, NULL) == DEATTACK_DETECTED)
                packet_disconnect("crc32 compensation attack: network attack detected");
 
        /* Decrypt data to incoming_packet. */
        buffer_clear(&incoming_packet);
        cp = buffer_append_space(&incoming_packet, padded_len);
-       cipher_decrypt(&receive_context, cp, buffer_ptr(&input), padded_len);
+       cipher_crypt(&receive_context, cp, buffer_ptr(&input), padded_len);
 
        buffer_consume(&input, padded_len);
 
@@ -793,7 +801,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
                comp = &newkeys[MODE_IN]->comp;
        }
        maclen = mac && mac->enabled ? mac->mac_len : 0;
-       block_size = enc ? enc->cipher->block_size : 8;
+       block_size = enc ? enc->block_size : 8;
 
        if (packet_length == 0) {
                /*
@@ -804,7 +812,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
                        return SSH_MSG_NONE;
                buffer_clear(&incoming_packet);
                cp = buffer_append_space(&incoming_packet, block_size);
-               cipher_decrypt(&receive_context, cp, buffer_ptr(&input),
+               cipher_crypt(&receive_context, cp, buffer_ptr(&input),
                    block_size);
                ucp = buffer_ptr(&incoming_packet);
                packet_length = GET_32BIT(ucp);
@@ -833,7 +841,7 @@ packet_read_poll2(u_int32_t *seqnr_p)
        buffer_dump(&input);
 #endif
        cp = buffer_append_space(&incoming_packet, need);
-       cipher_decrypt(&receive_context, cp, buffer_ptr(&input), need);
+       cipher_crypt(&receive_context, cp, buffer_ptr(&input), need);
        buffer_consume(&input, need);
        /*
         * compute MAC over seqnr and packet,
This page took 1.571059 seconds and 5 git commands to generate.