Home | History | Annotate | Download | only in openssh
      1 /* $OpenBSD: cipher-bf1.c,v 1.6 2010/10/01 23:05:32 djm Exp $ */
      2 /*
      3  * Copyright (c) 2003 Markus Friedl.  All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  *
     14  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     15  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     16  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     17  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     18  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     19  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     20  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     21  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     23  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     24  */
     25 
     26 #include "includes.h"
     27 
     28 #include <sys/types.h>
     29 
     30 #include <openssl/evp.h>
     31 
     32 #include <stdarg.h>
     33 #include <string.h>
     34 
     35 #include "xmalloc.h"
     36 #include "log.h"
     37 
     38 #include "openbsd-compat/openssl-compat.h"
     39 
     40 /*
     41  * SSH1 uses a variation on Blowfish, all bytes must be swapped before
     42  * and after encryption/decryption. Thus the swap_bytes stuff (yuk).
     43  */
     44 
     45 const EVP_CIPHER * evp_ssh1_bf(void);
     46 
     47 static void
     48 swap_bytes(const u_char *src, u_char *dst, int n)
     49 {
     50 	u_char c[4];
     51 
     52 	/* Process 4 bytes every lap. */
     53 	for (n = n / 4; n > 0; n--) {
     54 		c[3] = *src++;
     55 		c[2] = *src++;
     56 		c[1] = *src++;
     57 		c[0] = *src++;
     58 
     59 		*dst++ = c[0];
     60 		*dst++ = c[1];
     61 		*dst++ = c[2];
     62 		*dst++ = c[3];
     63 	}
     64 }
     65 
     66 #ifdef SSH_OLD_EVP
     67 static void bf_ssh1_init (EVP_CIPHER_CTX * ctx, const unsigned char *key,
     68 			  const unsigned char *iv, int enc)
     69 {
     70 	if (iv != NULL)
     71 		memcpy (&(ctx->oiv[0]), iv, 8);
     72 	memcpy (&(ctx->iv[0]), &(ctx->oiv[0]), 8);
     73 	if (key != NULL)
     74 		BF_set_key (&(ctx->c.bf_ks), EVP_CIPHER_CTX_key_length (ctx),
     75 			    key);
     76 }
     77 #endif
     78 
     79 static int (*orig_bf)(EVP_CIPHER_CTX *, u_char *,
     80     const u_char *, LIBCRYPTO_EVP_INL_TYPE) = NULL;
     81 
     82 static int
     83 bf_ssh1_cipher(EVP_CIPHER_CTX *ctx, u_char *out, const u_char *in,
     84     LIBCRYPTO_EVP_INL_TYPE len)
     85 {
     86 	int ret;
     87 
     88 	swap_bytes(in, out, len);
     89 	ret = (*orig_bf)(ctx, out, out, len);
     90 	swap_bytes(out, out, len);
     91 	return (ret);
     92 }
     93 
     94 const EVP_CIPHER *
     95 evp_ssh1_bf(void)
     96 {
     97 	static EVP_CIPHER ssh1_bf;
     98 
     99 	memcpy(&ssh1_bf, EVP_bf_cbc(), sizeof(EVP_CIPHER));
    100 	orig_bf = ssh1_bf.do_cipher;
    101 	ssh1_bf.nid = NID_undef;
    102 #ifdef SSH_OLD_EVP
    103 	ssh1_bf.init = bf_ssh1_init;
    104 #endif
    105 	ssh1_bf.do_cipher = bf_ssh1_cipher;
    106 	ssh1_bf.key_len = 32;
    107 	return (&ssh1_bf);
    108 }
    109