]> asedeno.scripts.mit.edu Git - PuTTY.git/commitdiff
Allow a cipher to specify encryption of the packet length.
authorChris Staite <chris@yourdreamnet.co.uk>
Sun, 7 Jun 2015 11:51:24 +0000 (12:51 +0100)
committerSimon Tatham <anakin@pobox.com>
Sun, 7 Jun 2015 12:42:31 +0000 (13:42 +0100)
No cipher uses this facility yet, but one shortly will.

ssh.c
ssh.h
sshaes.c
ssharcf.c
sshblowf.c
sshdes.c

diff --git a/ssh.c b/ssh.c
index 0b323d322e69f365d6544efa4e99349ad35adeb1..1a069c26a3e2dc8ccfcbf8013f4ab3974c95184f 100644 (file)
--- a/ssh.c
+++ b/ssh.c
@@ -1649,7 +1649,7 @@ static struct Packet *ssh2_rdpkt(Ssh ssh, const unsigned char **data,
 
         /*
          * OpenSSH encrypt-then-MAC mode: the packet length is
-         * unencrypted.
+         * unencrypted, unless the cipher supports length encryption.
          */
        for (st->i = st->len = 0; st->i < 4; st->i++) {
            while ((*datalen) == 0)
@@ -1657,7 +1657,16 @@ static struct Packet *ssh2_rdpkt(Ssh ssh, const unsigned char **data,
            st->pktin->data[st->i] = *(*data)++;
            (*datalen)--;
        }
-       st->len = toint(GET_32BIT(st->pktin->data));
+        /* Cipher supports length decryption, so do it */
+        if (ssh->sccipher && (ssh->sccipher->flags & SSH_CIPHER_SEPARATE_LENGTH)) {
+            /* Keep the packet the same though, so the MAC passes */
+            unsigned char len[4];
+            memcpy(len, st->pktin->data, 4);
+            ssh->sccipher->decrypt_length(ssh->sc_cipher_ctx, len, 4, st->incoming_sequence);
+            st->len = toint(GET_32BIT(len));
+        } else {
+            st->len = toint(GET_32BIT(st->pktin->data));
+        }
 
        /*
         * _Completely_ silly lengths should be stomped on before they
@@ -2277,6 +2286,13 @@ static int ssh2_pkt_construct(Ssh ssh, struct Packet *pkt)
     for (i = 0; i < padding; i++)
        pkt->data[pkt->length + i] = random_byte();
     PUT_32BIT(pkt->data, pkt->length + padding - 4);
+
+    /* Encrypt length if the scheme requires it */
+    if (ssh->cscipher && (ssh->cscipher->flags & SSH_CIPHER_SEPARATE_LENGTH)) {
+        ssh->cscipher->encrypt_length(ssh->cs_cipher_ctx, pkt->data, 4,
+                                      ssh->v2_outgoing_sequence);
+    }
+
     if (ssh->csmac && ssh->csmac_etm) {
         /*
          * OpenSSH-defined encrypt-then-MAC protocol.
diff --git a/ssh.h b/ssh.h
index 0bcf2b67a1bcf09f3154b924c3cd6abda047aa6b..111fca91a9faf0fd9c4529862dfe52125dc6657e 100644 (file)
--- a/ssh.h
+++ b/ssh.h
@@ -314,11 +314,15 @@ struct ssh2_cipher {
     void (*setkey) (void *, unsigned char *key);/* for SSH-2 */
     void (*encrypt) (void *, unsigned char *blk, int len);
     void (*decrypt) (void *, unsigned char *blk, int len);
+    /* Ignored unless SSH_CIPHER_SEPARATE_LENGTH flag set */
+    void (*encrypt_length) (void *, unsigned char *blk, int len, unsigned long seq);
+    void (*decrypt_length) (void *, unsigned char *blk, int len, unsigned long seq);
     const char *name;
     int blksize;
     int keylen;
     unsigned int flags;
 #define SSH_CIPHER_IS_CBC      1
+#define SSH_CIPHER_SEPARATE_LENGTH      2
     const char *text_name;
     /* If set, this takes priority over other MAC. */
     const struct ssh_mac *required_mac;
index 83cc1bb3449bf6a68d92bcc4542204036247afc2..0465d8792c29319b11c065a38a38111d34de15da 100644 (file)
--- a/sshaes.c
+++ b/sshaes.c
@@ -1171,7 +1171,7 @@ void aes256_decrypt_pubkey(unsigned char *key, unsigned char *blk, int len)
 
 static const struct ssh2_cipher ssh_aes128_ctr = {
     aes_make_context, aes_free_context, aes_iv, aes128_key,
-    aes_ssh2_sdctr, aes_ssh2_sdctr,
+    aes_ssh2_sdctr, aes_ssh2_sdctr, NULL, NULL,
     "aes128-ctr",
     16, 128, 0, "AES-128 SDCTR",
     NULL
@@ -1179,7 +1179,7 @@ static const struct ssh2_cipher ssh_aes128_ctr = {
 
 static const struct ssh2_cipher ssh_aes192_ctr = {
     aes_make_context, aes_free_context, aes_iv, aes192_key,
-    aes_ssh2_sdctr, aes_ssh2_sdctr,
+    aes_ssh2_sdctr, aes_ssh2_sdctr, NULL, NULL,
     "aes192-ctr",
     16, 192, 0, "AES-192 SDCTR",
     NULL
@@ -1187,7 +1187,7 @@ static const struct ssh2_cipher ssh_aes192_ctr = {
 
 static const struct ssh2_cipher ssh_aes256_ctr = {
     aes_make_context, aes_free_context, aes_iv, aes256_key,
-    aes_ssh2_sdctr, aes_ssh2_sdctr,
+    aes_ssh2_sdctr, aes_ssh2_sdctr, NULL, NULL,
     "aes256-ctr",
     16, 256, 0, "AES-256 SDCTR",
     NULL
@@ -1195,7 +1195,7 @@ static const struct ssh2_cipher ssh_aes256_ctr = {
 
 static const struct ssh2_cipher ssh_aes128 = {
     aes_make_context, aes_free_context, aes_iv, aes128_key,
-    aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
+    aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, NULL, NULL,
     "aes128-cbc",
     16, 128, SSH_CIPHER_IS_CBC, "AES-128 CBC",
     NULL
@@ -1203,7 +1203,7 @@ static const struct ssh2_cipher ssh_aes128 = {
 
 static const struct ssh2_cipher ssh_aes192 = {
     aes_make_context, aes_free_context, aes_iv, aes192_key,
-    aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
+    aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, NULL, NULL,
     "aes192-cbc",
     16, 192, SSH_CIPHER_IS_CBC, "AES-192 CBC",
     NULL
@@ -1211,7 +1211,7 @@ static const struct ssh2_cipher ssh_aes192 = {
 
 static const struct ssh2_cipher ssh_aes256 = {
     aes_make_context, aes_free_context, aes_iv, aes256_key,
-    aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
+    aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, NULL, NULL,
     "aes256-cbc",
     16, 256, SSH_CIPHER_IS_CBC, "AES-256 CBC",
     NULL
@@ -1219,7 +1219,7 @@ static const struct ssh2_cipher ssh_aes256 = {
 
 static const struct ssh2_cipher ssh_rijndael_lysator = {
     aes_make_context, aes_free_context, aes_iv, aes256_key,
-    aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk,
+    aes_ssh2_encrypt_blk, aes_ssh2_decrypt_blk, NULL, NULL,
     "rijndael-cbc@lysator.liu.se",
     16, 256, SSH_CIPHER_IS_CBC, "AES-256 CBC",
     NULL
index cec65c11505a26e0cca6ef4cd8e9f7b7a3425521..a9d5f7da037e115b43d563e10b69821b1164c3aa 100644 (file)
--- a/ssharcf.c
+++ b/ssharcf.c
@@ -100,7 +100,7 @@ static void arcfour_iv(void *handle, unsigned char *key)
 
 const struct ssh2_cipher ssh_arcfour128_ssh2 = {
     arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour128_key,
-    arcfour_block, arcfour_block,
+    arcfour_block, arcfour_block, NULL, NULL,
     "arcfour128",
     1, 128, 0, "Arcfour-128",
     NULL
@@ -108,7 +108,7 @@ const struct ssh2_cipher ssh_arcfour128_ssh2 = {
 
 const struct ssh2_cipher ssh_arcfour256_ssh2 = {
     arcfour_make_context, arcfour_free_context, arcfour_iv, arcfour256_key,
-    arcfour_block, arcfour_block,
+    arcfour_block, arcfour_block, NULL, NULL,
     "arcfour256",
     1, 256, 0, "Arcfour-256",
     NULL
index bf0b16419a9477a92adce249ab854812d2947219..8a561b37ebce804c4ab4f4d5fef916f476846bda 100644 (file)
@@ -641,7 +641,7 @@ const struct ssh_cipher ssh_blowfish_ssh1 = {
 
 static const struct ssh2_cipher ssh_blowfish_ssh2 = {
     blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish_key,
-    blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk,
+    blowfish_ssh2_encrypt_blk, blowfish_ssh2_decrypt_blk, NULL, NULL,
     "blowfish-cbc",
     8, 128, SSH_CIPHER_IS_CBC, "Blowfish-128 CBC",
     NULL
@@ -649,7 +649,7 @@ static const struct ssh2_cipher ssh_blowfish_ssh2 = {
 
 static const struct ssh2_cipher ssh_blowfish_ssh2_ctr = {
     blowfish_make_context, blowfish_free_context, blowfish_iv, blowfish256_key,
-    blowfish_ssh2_sdctr, blowfish_ssh2_sdctr,
+    blowfish_ssh2_sdctr, blowfish_ssh2_sdctr, NULL, NULL,
     "blowfish-ctr",
     8, 256, 0, "Blowfish-256 SDCTR",
     NULL
index 2f3e3c7a766fb7fe10782cfa037bf361d8db308e..9276fe06ca34f55ac1ec881b39399bf6ae9f1d86 100644 (file)
--- a/sshdes.c
+++ b/sshdes.c
@@ -947,7 +947,7 @@ void des_decrypt_xdmauth(const unsigned char *keydata,
 
 static const struct ssh2_cipher ssh_3des_ssh2 = {
     des3_make_context, des3_free_context, des3_iv, des3_key,
-    des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk,
+    des3_ssh2_encrypt_blk, des3_ssh2_decrypt_blk, NULL, NULL,
     "3des-cbc",
     8, 168, SSH_CIPHER_IS_CBC, "triple-DES CBC",
     NULL
@@ -955,7 +955,7 @@ static const struct ssh2_cipher ssh_3des_ssh2 = {
 
 static const struct ssh2_cipher ssh_3des_ssh2_ctr = {
     des3_make_context, des3_free_context, des3_iv, des3_key,
-    des3_ssh2_sdctr, des3_ssh2_sdctr,
+    des3_ssh2_sdctr, des3_ssh2_sdctr, NULL, NULL,
     "3des-ctr",
     8, 168, 0, "triple-DES SDCTR",
     NULL
@@ -971,7 +971,7 @@ static const struct ssh2_cipher ssh_3des_ssh2_ctr = {
  */
 static const struct ssh2_cipher ssh_des_ssh2 = {
     des_make_context, des3_free_context, des3_iv, des_key,
-    des_ssh2_encrypt_blk, des_ssh2_decrypt_blk,
+    des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, NULL, NULL,
     "des-cbc",
     8, 56, SSH_CIPHER_IS_CBC, "single-DES CBC",
     NULL
@@ -979,7 +979,7 @@ static const struct ssh2_cipher ssh_des_ssh2 = {
 
 static const struct ssh2_cipher ssh_des_sshcom_ssh2 = {
     des_make_context, des3_free_context, des3_iv, des_key,
-    des_ssh2_encrypt_blk, des_ssh2_decrypt_blk,
+    des_ssh2_encrypt_blk, des_ssh2_decrypt_blk, NULL, NULL,
     "des-cbc@ssh.com",
     8, 56, SSH_CIPHER_IS_CBC, "single-DES CBC",
     NULL