]> andersk Git - openssh.git/blobdiff - cipher.c
- djm@cvs.openbsd.org 2010/01/30 02:54:53
[openssh.git] / cipher.c
index b6637b6456f46b2ded6abe9c626af03590a26179..bb5c0ac3a2c2a02a7004822ccd25f893e37b4f29 100644 (file)
--- a/cipher.c
+++ b/cipher.c
@@ -1,3 +1,4 @@
+/* $OpenBSD: cipher.c,v 1.82 2009/01/26 09:58:15 markus Exp $ */
 /*
  * Author: Tatu Ylonen <ylo@cs.hut.fi>
  * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
  */
 
 #include "includes.h"
-RCSID("$OpenBSD: cipher.c,v 1.63 2003/04/12 10:13:57 markus Exp $");
+
+#include <sys/types.h>
+
+#include <openssl/md5.h>
+
+#include <string.h>
+#include <stdarg.h>
 
 #include "xmalloc.h"
 #include "log.h"
 #include "cipher.h"
 
-#include <openssl/md5.h>
+/* compatibility with old or broken OpenSSL versions */
+#include "openbsd-compat/openssl-compat.h"
 
-#if OPENSSL_VERSION_NUMBER < 0x00906000L
-#define SSH_OLD_EVP
-#define EVP_CIPHER_CTX_get_app_data(e)          ((e)->app_data)
-#endif
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-#include "rijndael.h"
-static const EVP_CIPHER *evp_rijndael(void);
-#endif
-static const EVP_CIPHER *evp_ssh1_3des(void);
-static const EVP_CIPHER *evp_ssh1_bf(void);
+extern const EVP_CIPHER *evp_ssh1_bf(void);
+extern const EVP_CIPHER *evp_ssh1_3des(void);
+extern void ssh1_3des_iv(EVP_CIPHER_CTX *, int, u_char *, int);
+extern const EVP_CIPHER *evp_aes_128_ctr(void);
+extern void ssh_aes_ctr_iv(EVP_CIPHER_CTX *, int, u_char *, u_int);
 
 struct Cipher {
        char    *name;
        int     number;         /* for ssh1 only */
        u_int   block_size;
        u_int   key_len;
+       u_int   discard_len;
+       u_int   cbc_mode;
        const EVP_CIPHER        *(*evptype)(void);
 } ciphers[] = {
-       { "none",               SSH_CIPHER_NONE, 8, 0, EVP_enc_null },
-       { "des",                SSH_CIPHER_DES, 8, 8, EVP_des_cbc },
-       { "3des",               SSH_CIPHER_3DES, 8, 16, evp_ssh1_3des },
-       { "blowfish",           SSH_CIPHER_BLOWFISH, 8, 32, evp_ssh1_bf },
-
-       { "3des-cbc",           SSH_CIPHER_SSH2, 8, 24, EVP_des_ede3_cbc },
-       { "blowfish-cbc",       SSH_CIPHER_SSH2, 8, 16, EVP_bf_cbc },
-       { "cast128-cbc",        SSH_CIPHER_SSH2, 8, 16, EVP_cast5_cbc },
-       { "arcfour",            SSH_CIPHER_SSH2, 8, 16, EVP_rc4 },
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-       { "aes128-cbc",         SSH_CIPHER_SSH2, 16, 16, evp_rijndael },
-       { "aes192-cbc",         SSH_CIPHER_SSH2, 16, 24, evp_rijndael },
-       { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
-       { "rijndael-cbc@lysator.liu.se",
-                               SSH_CIPHER_SSH2, 16, 32, evp_rijndael },
-#else
-       { "aes128-cbc",         SSH_CIPHER_SSH2, 16, 16, EVP_aes_128_cbc },
-       { "aes192-cbc",         SSH_CIPHER_SSH2, 16, 24, EVP_aes_192_cbc },
-       { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
+       { "none",               SSH_CIPHER_NONE, 8, 0, 0, 0, EVP_enc_null },
+       { "des",                SSH_CIPHER_DES, 8, 8, 0, 1, EVP_des_cbc },
+       { "3des",               SSH_CIPHER_3DES, 8, 16, 0, 1, evp_ssh1_3des },
+       { "blowfish",           SSH_CIPHER_BLOWFISH, 8, 32, 0, 1, evp_ssh1_bf },
+
+       { "3des-cbc",           SSH_CIPHER_SSH2, 8, 24, 0, 1, EVP_des_ede3_cbc },
+       { "blowfish-cbc",       SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_bf_cbc },
+       { "cast128-cbc",        SSH_CIPHER_SSH2, 8, 16, 0, 1, EVP_cast5_cbc },
+       { "arcfour",            SSH_CIPHER_SSH2, 8, 16, 0, 0, EVP_rc4 },
+       { "arcfour128",         SSH_CIPHER_SSH2, 8, 16, 1536, 0, EVP_rc4 },
+       { "arcfour256",         SSH_CIPHER_SSH2, 8, 32, 1536, 0, EVP_rc4 },
+       { "aes128-cbc",         SSH_CIPHER_SSH2, 16, 16, 0, 1, EVP_aes_128_cbc },
+       { "aes192-cbc",         SSH_CIPHER_SSH2, 16, 24, 0, 1, EVP_aes_192_cbc },
+       { "aes256-cbc",         SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
        { "rijndael-cbc@lysator.liu.se",
-                               SSH_CIPHER_SSH2, 16, 32, EVP_aes_256_cbc },
+                               SSH_CIPHER_SSH2, 16, 32, 0, 1, EVP_aes_256_cbc },
+       { "aes128-ctr",         SSH_CIPHER_SSH2, 16, 16, 0, 0, evp_aes_128_ctr },
+       { "aes192-ctr",         SSH_CIPHER_SSH2, 16, 24, 0, 0, evp_aes_128_ctr },
+       { "aes256-ctr",         SSH_CIPHER_SSH2, 16, 32, 0, 0, evp_aes_128_ctr },
+#ifdef USE_CIPHER_ACSS
+       { "acss@openssh.org",   SSH_CIPHER_SSH2, 16, 5, 0, 0, EVP_acss },
 #endif
-
-       { NULL,                 SSH_CIPHER_ILLEGAL, 0, 0, NULL }
+       { NULL,                 SSH_CIPHER_INVALID, 0, 0, 0, 0, NULL }
 };
 
 /*--*/
 
 u_int
-cipher_blocksize(Cipher *c)
+cipher_blocksize(const Cipher *c)
 {
        return (c->block_size);
 }
 
 u_int
-cipher_keylen(Cipher *c)
+cipher_keylen(const Cipher *c)
 {
        return (c->key_len);
 }
 
 u_int
-cipher_get_number(Cipher *c)
+cipher_get_number(const Cipher *c)
 {
        return (c->number);
 }
 
+u_int
+cipher_is_cbc(const Cipher *c)
+{
+       return (c->cbc_mode);
+}
+
 u_int
 cipher_mask_ssh1(int client)
 {
@@ -125,7 +134,7 @@ cipher_by_name(const char *name)
 {
        Cipher *c;
        for (c = ciphers; c->name != NULL; c++)
-               if (strcasecmp(c->name, name) == 0)
+               if (strcmp(c->name, name) == 0)
                        return c;
        return NULL;
 }
@@ -145,25 +154,25 @@ int
 ciphers_valid(const char *names)
 {
        Cipher *c;
-       char *ciphers, *cp;
+       char *cipher_list, *cp;
        char *p;
 
        if (names == NULL || strcmp(names, "") == 0)
                return 0;
-       ciphers = cp = xstrdup(names);
+       cipher_list = cp = xstrdup(names);
        for ((p = strsep(&cp, CIPHER_SEP)); p && *p != '\0';
            (p = strsep(&cp, CIPHER_SEP))) {
                c = cipher_by_name(p);
                if (c == NULL || c->number != SSH_CIPHER_SSH2) {
                        debug("bad cipher %s [%s]", p, names);
-                       xfree(ciphers);
+                       xfree(cipher_list);
                        return 0;
                } else {
                        debug3("cipher ok: %s [%s]", p, names);
                }
        }
        debug3("ciphers ok: [%s]", names);
-       xfree(ciphers);
+       xfree(cipher_list);
        return 1;
 }
 
@@ -178,8 +187,10 @@ cipher_number(const char *name)
        Cipher *c;
        if (name == NULL)
                return -1;
-       c = cipher_by_name(name);
-       return (c==NULL) ? -1 : c->number;
+       for (c = ciphers; c->name != NULL; c++)
+               if (strcasecmp(c->name, name) == 0)
+                       return c->number;
+       return -1;
 }
 
 char *
@@ -192,15 +203,16 @@ 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,
-    int encrypt)
+    int do_encrypt)
 {
        static int dowarn = 1;
 #ifdef SSH_OLD_EVP
        EVP_CIPHER *type;
 #else
        const EVP_CIPHER *type;
-#endif
        int klen;
+#endif
+       u_char *junk, *discard;
 
        if (cipher->number == SSH_CIPHER_DES) {
                if (dowarn) {
@@ -231,14 +243,14 @@ cipher_init(CipherContext *cc, Cipher *cipher,
                type->key_len = keylen;
        }
        EVP_CipherInit(&cc->evp, type, (u_char *)key, (u_char *)iv,
-           (encrypt == CIPHER_ENCRYPT));
+           (do_encrypt == CIPHER_ENCRYPT));
 #else
        if (EVP_CipherInit(&cc->evp, type, NULL, (u_char *)iv,
-           (encrypt == CIPHER_ENCRYPT)) == 0)
+           (do_encrypt == CIPHER_ENCRYPT)) == 0)
                fatal("cipher_init: EVP_CipherInit failed for %s",
                    cipher->name);
        klen = EVP_CIPHER_CTX_key_length(&cc->evp);
-       if (klen > 0 && keylen != klen) {
+       if (klen > 0 && keylen != (u_int)klen) {
                debug2("cipher_init: set keylen (%d -> %d)", klen, keylen);
                if (EVP_CIPHER_CTX_set_key_length(&cc->evp, keylen) == 0)
                        fatal("cipher_init: set keylen failed (%d -> %d)",
@@ -248,6 +260,17 @@ cipher_init(CipherContext *cc, Cipher *cipher,
                fatal("cipher_init: EVP_CipherInit: set key failed for %s",
                    cipher->name);
 #endif
+
+       if (cipher->discard_len > 0) {
+               junk = xmalloc(cipher->discard_len);
+               discard = xmalloc(cipher->discard_len);
+               if (EVP_Cipher(&cc->evp, discard, junk,
+                   cipher->discard_len) == 0)
+                       fatal("evp_crypt: EVP_Cipher failed during discard");
+               memset(discard, 0, cipher->discard_len);
+               xfree(junk);
+               xfree(discard);
+       }
 }
 
 void
@@ -255,23 +278,15 @@ 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);
-#ifdef SSH_OLD_EVP
-       EVP_Cipher(&cc->evp, dest, (u_char *)src, len);
-#else
        if (EVP_Cipher(&cc->evp, dest, (u_char *)src, len) == 0)
                fatal("evp_crypt: EVP_Cipher failed");
-#endif
 }
 
 void
 cipher_cleanup(CipherContext *cc)
 {
-#ifdef SSH_OLD_EVP
-       EVP_CIPHER_CTX_cleanup(&cc->evp);
-#else
        if (EVP_CIPHER_CTX_cleanup(&cc->evp) == 0)
                error("cipher_cleanup: EVP_CIPHER_CTX_cleanup failed");
-#endif
 }
 
 /*
@@ -281,7 +296,7 @@ cipher_cleanup(CipherContext *cc)
 
 void
 cipher_set_key_string(CipherContext *cc, Cipher *cipher,
-    const char *passphrase, int encrypt)
+    const char *passphrase, int do_encrypt)
 {
        MD5_CTX md;
        u_char digest[16];
@@ -290,339 +305,12 @@ 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, encrypt);
+       cipher_init(cc, cipher, digest, 16, NULL, 0, do_encrypt);
 
        memset(digest, 0, sizeof(digest));
        memset(&md, 0, sizeof(md));
 }
 
-/* Implementations for other non-EVP ciphers */
-
-/*
- * This is used by SSH1:
- *
- * What kind of triple DES are these 2 routines?
- *
- * Why is there a redundant initialization vector?
- *
- * If only iv3 was used, then, this would till effect have been
- * outer-cbc. However, there is also a private iv1 == iv2 which
- * perhaps makes differential analysis easier. On the other hand, the
- * private iv1 probably makes the CRC-32 attack ineffective. This is a
- * result of that there is no longer any known iv1 to use when
- * choosing the X block.
- */
-struct ssh1_3des_ctx
-{
-       EVP_CIPHER_CTX  k1, k2, k3;
-};
-
-static int
-ssh1_3des_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
-    int enc)
-{
-       struct ssh1_3des_ctx *c;
-       u_char *k1, *k2, *k3;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-               c = xmalloc(sizeof(*c));
-               EVP_CIPHER_CTX_set_app_data(ctx, c);
-       }
-       if (key == NULL)
-               return (1);
-       if (enc == -1)
-               enc = ctx->encrypt;
-       k1 = k2 = k3 = (u_char *) key;
-       k2 += 8;
-       if (EVP_CIPHER_CTX_key_length(ctx) >= 16+8) {
-               if (enc)
-                       k3 += 16;
-               else
-                       k1 += 16;
-       }
-       EVP_CIPHER_CTX_init(&c->k1);
-       EVP_CIPHER_CTX_init(&c->k2);
-       EVP_CIPHER_CTX_init(&c->k3);
-#ifdef SSH_OLD_EVP
-       EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc);
-       EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc);
-       EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc);
-#else
-       if (EVP_CipherInit(&c->k1, EVP_des_cbc(), k1, NULL, enc) == 0 ||
-           EVP_CipherInit(&c->k2, EVP_des_cbc(), k2, NULL, !enc) == 0 ||
-           EVP_CipherInit(&c->k3, EVP_des_cbc(), k3, NULL, enc) == 0) {
-               memset(c, 0, sizeof(*c));
-               xfree(c);
-               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-               return (0);
-       }
-#endif
-       return (1);
-}
-
-static int
-ssh1_3des_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src, u_int len)
-{
-       struct ssh1_3des_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-               error("ssh1_3des_cbc: no context");
-               return (0);
-       }
-#ifdef SSH_OLD_EVP
-       EVP_Cipher(&c->k1, dest, (u_char *)src, len);
-       EVP_Cipher(&c->k2, dest, dest, len);
-       EVP_Cipher(&c->k3, dest, dest, len);
-#else
-       if (EVP_Cipher(&c->k1, dest, (u_char *)src, len) == 0 ||
-           EVP_Cipher(&c->k2, dest, dest, len) == 0 ||
-           EVP_Cipher(&c->k3, dest, dest, len) == 0)
-               return (0);
-#endif
-       return (1);
-}
-
-static int
-ssh1_3des_cleanup(EVP_CIPHER_CTX *ctx)
-{
-       struct ssh1_3des_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-               memset(c, 0, sizeof(*c));
-               xfree(c);
-               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-       }
-       return (1);
-}
-
-static void
-ssh1_3des_iv(EVP_CIPHER_CTX *evp, int doset, u_char *iv, int len)
-{
-       struct ssh1_3des_ctx *c;
-
-       if (len != 24)
-               fatal("%s: bad 3des iv length: %d", __func__, len);
-       if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
-               fatal("%s: no 3des context", __func__);
-       if (doset) {
-               debug3("%s: Installed 3DES IV", __func__);
-               memcpy(c->k1.iv, iv, 8);
-               memcpy(c->k2.iv, iv + 8, 8);
-               memcpy(c->k3.iv, iv + 16, 8);
-       } else {
-               debug3("%s: Copying 3DES IV", __func__);
-               memcpy(iv, c->k1.iv, 8);
-               memcpy(iv + 8, c->k2.iv, 8);
-               memcpy(iv + 16, c->k3.iv, 8);
-       }
-}
-
-static const EVP_CIPHER *
-evp_ssh1_3des(void)
-{
-       static EVP_CIPHER ssh1_3des;
-
-       memset(&ssh1_3des, 0, sizeof(EVP_CIPHER));
-       ssh1_3des.nid = NID_undef;
-       ssh1_3des.block_size = 8;
-       ssh1_3des.iv_len = 0;
-       ssh1_3des.key_len = 16;
-       ssh1_3des.init = ssh1_3des_init;
-       ssh1_3des.cleanup = ssh1_3des_cleanup;
-       ssh1_3des.do_cipher = ssh1_3des_cbc;
-#ifndef SSH_OLD_EVP
-       ssh1_3des.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH;
-#endif
-       return (&ssh1_3des);
-}
-
-/*
- * SSH1 uses a variation on Blowfish, all bytes must be swapped before
- * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
- */
-static void
-swap_bytes(const u_char *src, u_char *dst, int n)
-{
-       u_char c[4];
-
-       /* Process 4 bytes every lap. */
-       for (n = n / 4; n > 0; n--) {
-               c[3] = *src++;
-               c[2] = *src++;
-               c[1] = *src++;
-               c[0] = *src++;
-
-               *dst++ = c[0];
-               *dst++ = c[1];
-               *dst++ = c[2];
-               *dst++ = c[3];
-       }
-}
-
-#ifdef SSH_OLD_EVP
-static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
-                         const unsigned char *iv, int enc)
-{
-       if (iv != NULL)
-               memcpy (&(ctx->oiv[0]), iv, 8);
-       memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8);
-       if (key != NULL)
-               BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx),
-                           key);
-}
-#endif
-static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *, const u_char *, u_int) = NULL;
-
-static int
-bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in, u_int len)
-{
-       int ret;
-
-       swap_bytes(in, out, len);
-       ret = (*orig_bf)(ctx, out, out, len);
-       swap_bytes(out, out, len);
-       return (ret);
-}
-
-static const EVP_CIPHER *
-evp_ssh1_bf(void)
-{
-       static EVP_CIPHER ssh1_bf;
-
-       memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
-       orig_bf = ssh1_bf.do_cipher;
-       ssh1_bf.nid = NID_undef;
-#ifdef SSH_OLD_EVP
-       ssh1_bf.init = bf_ssh1_init;
-#endif
-       ssh1_bf.do_cipher = bf_ssh1_cipher;
-       ssh1_bf.key_len = 32;
-       return (&ssh1_bf);
-}
-
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
-/* RIJNDAEL */
-#define RIJNDAEL_BLOCKSIZE 16
-struct ssh_rijndael_ctx
-{
-       rijndael_ctx    r_ctx;
-       u_char          r_iv[RIJNDAEL_BLOCKSIZE];
-};
-
-static int
-ssh_rijndael_init(EVP_CIPHER_CTX *ctx, const u_char *key, const u_char *iv,
-    int enc)
-{
-       struct ssh_rijndael_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-               c = xmalloc(sizeof(*c));
-               EVP_CIPHER_CTX_set_app_data(ctx, c);
-       }
-       if (key != NULL) {
-               if (enc == -1)
-                       enc = ctx->encrypt;
-               rijndael_set_key(&c->r_ctx, (u_char *)key,
-                   8*EVP_CIPHER_CTX_key_length(ctx), enc);
-       }
-       if (iv != NULL)
-               memcpy(c->r_iv, iv, RIJNDAEL_BLOCKSIZE);
-       return (1);
-}
-
-static int
-ssh_rijndael_cbc(EVP_CIPHER_CTX *ctx, u_char *dest, const u_char *src,
-    u_int len)
-{
-       struct ssh_rijndael_ctx *c;
-       u_char buf[RIJNDAEL_BLOCKSIZE];
-       u_char *cprev, *cnow, *plain, *ivp;
-       int i, j, blocks = len / RIJNDAEL_BLOCKSIZE;
-
-       if (len == 0)
-               return (1);
-       if (len % RIJNDAEL_BLOCKSIZE)
-               fatal("ssh_rijndael_cbc: bad len %d", len);
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) == NULL) {
-               error("ssh_rijndael_cbc: no context");
-               return (0);
-       }
-       if (ctx->encrypt) {
-               cnow  = dest;
-               plain = (u_char *)src;
-               cprev = c->r_iv;
-               for (i = 0; i < blocks; i++, plain+=RIJNDAEL_BLOCKSIZE,
-                   cnow+=RIJNDAEL_BLOCKSIZE) {
-                       for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
-                               buf[j] = plain[j] ^ cprev[j];
-                       rijndael_encrypt(&c->r_ctx, buf, cnow);
-                       cprev = cnow;
-               }
-               memcpy(c->r_iv, cprev, RIJNDAEL_BLOCKSIZE);
-       } else {
-               cnow  = (u_char *) (src+len-RIJNDAEL_BLOCKSIZE);
-               plain = dest+len-RIJNDAEL_BLOCKSIZE;
-
-               memcpy(buf, cnow, RIJNDAEL_BLOCKSIZE);
-               for (i = blocks; i > 0; i--, cnow-=RIJNDAEL_BLOCKSIZE,
-                   plain-=RIJNDAEL_BLOCKSIZE) {
-                       rijndael_decrypt(&c->r_ctx, cnow, plain);
-                       ivp = (i == 1) ? c->r_iv : cnow-RIJNDAEL_BLOCKSIZE;
-                       for (j = 0; j < RIJNDAEL_BLOCKSIZE; j++)
-                               plain[j] ^= ivp[j];
-               }
-               memcpy(c->r_iv, buf, RIJNDAEL_BLOCKSIZE);
-       }
-       return (1);
-}
-
-static int
-ssh_rijndael_cleanup(EVP_CIPHER_CTX *ctx)
-{
-       struct ssh_rijndael_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(ctx)) != NULL) {
-               memset(c, 0, sizeof(*c));
-               xfree(c);
-               EVP_CIPHER_CTX_set_app_data(ctx, NULL);
-       }
-       return (1);
-}
-
-static void
-ssh_rijndael_iv(EVP_CIPHER_CTX *evp, int doset, u_char * iv, u_int len)
-{
-       struct ssh_rijndael_ctx *c;
-
-       if ((c = EVP_CIPHER_CTX_get_app_data(evp)) == NULL)
-               fatal("ssh_rijndael_iv: no context");
-       if (doset)
-               memcpy(c->r_iv, iv, len);
-       else
-               memcpy(iv, c->r_iv, len);
-}
-
-static const EVP_CIPHER *
-evp_rijndael(void)
-{
-       static EVP_CIPHER rijndal_cbc;
-
-       memset(&rijndal_cbc, 0, sizeof(EVP_CIPHER));
-       rijndal_cbc.nid = NID_undef;
-       rijndal_cbc.block_size = RIJNDAEL_BLOCKSIZE;
-       rijndal_cbc.iv_len = RIJNDAEL_BLOCKSIZE;
-       rijndal_cbc.key_len = 16;
-       rijndal_cbc.init = ssh_rijndael_init;
-       rijndal_cbc.cleanup = ssh_rijndael_cleanup;
-       rijndal_cbc.do_cipher = ssh_rijndael_cbc;
-#ifndef SSH_OLD_EVP
-       rijndal_cbc.flags = EVP_CIPH_CBC_MODE | EVP_CIPH_VARIABLE_LENGTH |
-           EVP_CIPH_ALWAYS_CALL_INIT | EVP_CIPH_CUSTOM_IV;
-#endif
-       return (&rijndal_cbc);
-}
-#endif
-
 /*
  * Exports an IV from the CipherContext required to export the key
  * state back from the unprivileged child to the privileged parent
@@ -630,7 +318,7 @@ evp_rijndael(void)
  */
 
 int
-cipher_get_keyiv_len(CipherContext *cc)
+cipher_get_keyiv_len(const CipherContext *cc)
 {
        Cipher *c = cc->cipher;
        int ivlen;
@@ -653,16 +341,19 @@ cipher_get_keyiv(CipherContext *cc, u_char *iv, u_int len)
        case SSH_CIPHER_DES:
        case SSH_CIPHER_BLOWFISH:
                evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
-               if (evplen == 0)
+               if (evplen <= 0)
                        return;
-               if (evplen != len)
+               if ((u_int)evplen != len)
                        fatal("%s: wrong iv length %d != %d", __func__,
                            evplen, len);
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
+#ifdef USE_BUILTIN_RIJNDAEL
                if (c->evptype == evp_rijndael)
                        ssh_rijndael_iv(&cc->evp, 0, iv, len);
                else
 #endif
+               if (c->evptype == evp_aes_128_ctr)
+                       ssh_aes_ctr_iv(&cc->evp, 0, iv, len);
+               else
                        memcpy(iv, cc->evp.iv, len);
                break;
        case SSH_CIPHER_3DES:
@@ -686,11 +377,14 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
                evplen = EVP_CIPHER_CTX_iv_length(&cc->evp);
                if (evplen == 0)
                        return;
-#if OPENSSL_VERSION_NUMBER < 0x00907000L
+#ifdef USE_BUILTIN_RIJNDAEL
                if (c->evptype == evp_rijndael)
                        ssh_rijndael_iv(&cc->evp, 1, iv, evplen);
                else
 #endif
+               if (c->evptype == evp_aes_128_ctr)
+                       ssh_aes_ctr_iv(&cc->evp, 1, iv, evplen);
+               else
                        memcpy(cc->evp.iv, iv, evplen);
                break;
        case SSH_CIPHER_3DES:
@@ -710,12 +404,12 @@ cipher_set_keyiv(CipherContext *cc, u_char *iv)
 #endif
 
 int
-cipher_get_keycontext(CipherContext *cc, u_char *dat)
+cipher_get_keycontext(const CipherContext *cc, u_char *dat)
 {
        Cipher *c = cc->cipher;
        int plen = 0;
 
-       if (c->evptype == EVP_rc4) {
+       if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
                plen = EVP_X_STATE_LEN(cc->evp);
                if (dat == NULL)
                        return (plen);
@@ -730,7 +424,7 @@ cipher_set_keycontext(CipherContext *cc, u_char *dat)
        Cipher *c = cc->cipher;
        int plen;
 
-       if (c->evptype == EVP_rc4) {
+       if (c->evptype == EVP_rc4 || c->evptype == EVP_acss) {
                plen = EVP_X_STATE_LEN(cc->evp);
                memcpy(EVP_X_STATE(cc->evp), dat, plen);
        }
This page took 0.062296 seconds and 4 git commands to generate.