Subject: kern/14439: Crypt support for vnd
To: None <gnats-bugs@gnats.netbsd.org>
From: None <lundman@lundman.net>
List: netbsd-bugs
Date: 11/03/2001 00:17:08
>Number:         14439
>Category:       kern
>Synopsis:       added support for simple encrypted vnd drives
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Fri Nov 02 16:18:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Jorgen Lundman
>Release:        NetBSD-current 01/11/01
>Organization:
	Lundtastic Services
>Environment:
	System: NetBSD netbsd 1.5 NetBSD 1.5 (netbsd) #7: Sat Oct 27 16:24:08 BST 2001 root@netbsd:/usr/src/sys/arch/i386/compile/netbsd i386


>Description:
	Tested on i386 and sparc. Had to change some files in crypto/ as well
        in particular bf_cbc.c which seemed to have been rolled back prior to
        1.5 (please verify).
        Supplied two patches, first to be applied from /usr/src/sys/ and
        second inside /usr/src/usr.sbin/vnconfig/
        Look for the "cut here" line.

>How-To-Repeat:
        N/A
>Fix:

diff -u -r --exclude=arch/sparc/* --exclude=*~ --exclude=CVS ./conf/files /mnt/src/sys/conf/files
--- ./conf/files	Fri Nov  2 23:23:44 2001
+++ /mnt/src/sys/conf/files	Fri Nov  2 19:01:42 2001
@@ -737,9 +737,9 @@
 file	crypto/des/des_setkey.c		ipsec & ipsec_esp
 file	crypto/des/des_enc.c		ipsec & ipsec_esp & !crypto_md_des_enc
 #file    crypto/des/des_cbc.c		ipsec & ipsec_esp & !crypto_md_des_cbc
-file	crypto/blowfish/bf_enc.c	ipsec & ipsec_esp & !crypto_md_bf_enc
-#file	crypto/blowfish/bf_cbc.c	ipsec & ipsec_esp & !crypto_md_bf_cbc
-file	crypto/blowfish/bf_skey.c	ipsec & ipsec_esp
+file	crypto/blowfish/bf_enc.c	ipsec & ipsec_esp & !crypto_md_bf_enc | vnd
+file	crypto/blowfish/bf_cbc.c	ipsec & ipsec_esp & !crypto_md_bf_cbc | vnd
+file	crypto/blowfish/bf_skey.c	ipsec & ipsec_esp | vnd
 file	crypto/cast128/cast128.c	ipsec & ipsec_esp
 file	crypto/rijndael/rijndael-alg-fst.c ipsec & ipsec_esp
 file	crypto/rijndael/rijndael-api-fst.c ipsec & ipsec_esp
diff -u -r --exclude=arch/sparc/* --exclude=*~ --exclude=CVS ./crypto/blowfish/bf_cbc.c /mnt/src/sys/crypto/blowfish/bf_cbc.c
--- ./crypto/blowfish/bf_cbc.c	Sun Sep  9 12:03:59 2001
+++ /mnt/src/sys/crypto/blowfish/bf_cbc.c	Fri Nov  2 21:40:23 2001
@@ -1,25 +1,28 @@
+/*	$NetBSD: bf_cbc.c,v 1.1.1.1.2.1 2000/08/31 07:50:37 itojun Exp $	*/
+/*	$KAME: bf_cbc.c,v 1.4 2000/08/31 05:41:02 itojun Exp $	*/
+
 /* crypto/bf/bf_cbc.c */
-/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
+/* Copyright (C) 1995-1997 Eric Young (eay@mincom.oz.au)
  * All rights reserved.
  *
  * This package is an SSL implementation written
- * by Eric Young (eay@cryptsoft.com).
+ * by Eric Young (eay@mincom.oz.au).
  * The implementation was written so as to conform with Netscapes SSL.
- * 
+ *
  * This library is free for commercial and non-commercial use as long as
  * the following conditions are aheared to.  The following conditions
  * apply to all code found in this distribution, be it the RC4, RSA,
  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
  * included with this distribution is covered by the same copyright terms
- * except that the holder is Tim Hudson (tjh@cryptsoft.com).
- * 
+ * except that the holder is Tim Hudson (tjh@mincom.oz.au).
+ *
  * Copyright remains Eric Young's, and as such any Copyright notices in
  * the code are not to be removed.
  * If this package is used in a product, Eric Young should be given attribution
  * as the author of the parts of the library used.
  * This can be in the form of a textual message at program startup or
  * in documentation (online or textual) provided with the package.
- * 
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -31,13 +34,13 @@
  * 3. All advertising materials mentioning features or use of this software
  *    must display the following acknowledgement:
  *    "This product includes cryptographic software written by
- *     Eric Young (eay@cryptsoft.com)"
+ *     Eric Young (eay@mincom.oz.au)"
  *    The word 'cryptographic' can be left out if the rouines from the library
  *    being used are not cryptographic related :-).
- * 4. If you include any Windows specific code (or a derivative thereof) from 
+ * 4. If you include any Windows specific code (or a derivative thereof) from
  *    the apps directory (application code) you must include an acknowledgement:
- *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
- * 
+ *    "This product includes software written by Tim Hudson (tjh@mincom.oz.au)"
+ *
  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
@@ -49,18 +52,24 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- * 
+ *
  * The licence and distribution terms for any publically available version or
  * derivative of this code cannot be changed.  i.e. this code cannot simply be
  * copied and put under another distribution licence
  * [including the GNU Public Licence.]
  */
 
-#include <openssl/blowfish.h>
-#include "bf_locl.h"
+#include <sys/types.h>
+#include <crypto/blowfish/blowfish.h>
+#include <crypto/blowfish/bf_locl.h>
 
-void BF_cbc_encrypt(const unsigned char *in, unsigned char *out, long length,
-	     const BF_KEY *schedule, unsigned char *ivec, int encrypt)
+void BF_cbc_encrypt(in, out, length, ks, iv, encrypt)
+const unsigned char *in;
+unsigned char *out;
+long length;
+BF_KEY *ks;
+unsigned char *iv;
+int encrypt;
 	{
 	register BF_LONG tin0,tin1;
 	register BF_LONG tout0,tout1,xor0,xor1;
@@ -69,9 +78,9 @@
 
 	if (encrypt)
 		{
-		n2l(ivec,tout0);
-		n2l(ivec,tout1);
-		ivec-=8;
+		n2l(iv,tout0);
+		n2l(iv,tout1);
+		iv-=8;
 		for (l-=8; l>=0; l-=8)
 			{
 			n2l(in,tin0);
@@ -80,7 +89,7 @@
 			tin1^=tout1;
 			tin[0]=tin0;
 			tin[1]=tin1;
-			BF_encrypt(tin,schedule);
+			BF_encrypt(tin,ks,BF_ENCRYPT);
 			tout0=tin[0];
 			tout1=tin[1];
 			l2n(tout0,out);
@@ -93,27 +102,27 @@
 			tin1^=tout1;
 			tin[0]=tin0;
 			tin[1]=tin1;
-			BF_encrypt(tin,schedule);
+			BF_encrypt(tin,ks,BF_ENCRYPT);
 			tout0=tin[0];
 			tout1=tin[1];
 			l2n(tout0,out);
 			l2n(tout1,out);
 			}
-		l2n(tout0,ivec);
-		l2n(tout1,ivec);
+		l2n(tout0,iv);
+		l2n(tout1,iv);
 		}
 	else
 		{
-		n2l(ivec,xor0);
-		n2l(ivec,xor1);
-		ivec-=8;
+		n2l(iv,xor0);
+		n2l(iv,xor1);
+		iv-=8;
 		for (l-=8; l>=0; l-=8)
 			{
 			n2l(in,tin0);
 			n2l(in,tin1);
 			tin[0]=tin0;
 			tin[1]=tin1;
-			BF_decrypt(tin,schedule);
+			BF_encrypt(tin,ks,BF_DECRYPT);
 			tout0=tin[0]^xor0;
 			tout1=tin[1]^xor1;
 			l2n(tout0,out);
@@ -127,15 +136,15 @@
 			n2l(in,tin1);
 			tin[0]=tin0;
 			tin[1]=tin1;
-			BF_decrypt(tin,schedule);
+			BF_encrypt(tin,ks,BF_DECRYPT);
 			tout0=tin[0]^xor0;
 			tout1=tin[1]^xor1;
 			l2nn(tout0,tout1,out,l+8);
 			xor0=tin0;
 			xor1=tin1;
 			}
-		l2n(xor0,ivec);
-		l2n(xor1,ivec);
+		l2n(xor0,iv);
+		l2n(xor1,iv);
 		}
 	tin0=tin1=tout0=tout1=xor0=xor1=0;
 	tin[0]=tin[1]=0;
diff -u -r --exclude=arch/sparc/* --exclude=*~ --exclude=CVS ./crypto/blowfish/blowfish.h /mnt/src/sys/crypto/blowfish/blowfish.h
--- ./crypto/blowfish/blowfish.h	Mon Sep 10 12:00:53 2001
+++ /mnt/src/sys/crypto/blowfish/blowfish.h	Fri Nov  2 21:40:16 2001
@@ -83,7 +83,7 @@
 void BF_set_key __P((BF_KEY *, int, unsigned char *));
 void BF_encrypt __P((BF_LONG *, BF_KEY *, int));
 void BF_cbc_encrypt(const unsigned char *, unsigned char *, long,
-		    const BF_KEY *, unsigned char *, int);
+		    BF_KEY *, unsigned char *, int);
 
 #ifdef  __cplusplus
 }
diff -u -r --exclude=arch/sparc/* --exclude=*~ --exclude=CVS ./dev/vnd.c /mnt/src/sys/dev/vnd.c
--- ./dev/vnd.c	Tue Oct 23 12:22:58 2001
+++ /mnt/src/sys/dev/vnd.c	Fri Nov  2 15:16:10 2001
@@ -1,4 +1,4 @@
-/*	$NetBSD: vnd.c,v 1.74 2001/10/22 16:43:55 mrg Exp $	*/
+/*	$NetBSD: vnd.c,v 1.65.4.1 2000/09/13 02:18:33 enami Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997, 1998 The NetBSD Foundation, Inc.
@@ -123,6 +123,14 @@
 
 #include <dev/vndvar.h>
 
+
+#ifdef VND_CIPHER
+#include <crypto/blowfish/blowfish.h>
+#endif
+
+
+#define VNDDEBUG
+
 #if defined(VNDDEBUG) && !defined(DEBUG)
 #define	DEBUG
 #endif
@@ -133,7 +141,8 @@
 #define	VDB_INIT	0x02
 #define	VDB_IO		0x04
 #define	VDB_LABEL	0x08
-int vnddebug = 0x00;
+#define VDB_CIPHER      0x10
+int vnddebug = 0x10;
 #endif
 
 #define	vndunit(x)	DISKUNIT(x)
@@ -179,6 +188,238 @@
 static	int vndlock __P((struct vnd_softc *));
 static	void vndunlock __P((struct vnd_softc *));
 
+
+
+#ifdef VND_CIPHER
+void vnd_encode(struct vnd_softc *, struct buf *);
+void vnd_decode(struct vnd_softc *, struct buf *);
+int  vnd_setkey(struct vnd_softc *, struct vnd_ioctl *);
+
+
+
+int vnd_setkey(struct vnd_softc *vnd, struct vnd_ioctl *vio)
+{
+  char *key;
+  int error; 
+
+  if (vio->cipher == VND_CIPHER_NONE) return 0; // No cipher, success
+
+  // We are to use a cipher, check we've been passed what we need
+  if ((vio->vnd_keylen <= 0) ||
+      (vio->vnd_key == NULL))
+    return EINVAL;
+
+  // If the key is too large / large than bsize, truncate it
+#if 0
+  if (vio->vnd_key > bsize)
+    vio->vnd_key = bsize;
+#endif
+
+
+  vnd->cipher     = VND_CIPHER_NONE; // Set it to none incase we fail.
+  vnd->vnd_keylen = 0;
+
+
+  // Allocate temp holder for the key
+  key = malloc(vio->vnd_keylen, M_TEMP, M_WAITOK);
+  
+  // Copy it into kernel space
+  if ((error = copyin((caddr_t)vio->vnd_key, key,
+		      vio->vnd_keylen)) != 0) {
+    return (error);
+  }
+  
+
+
+  switch(vio->cipher) {
+
+  case VND_CIPHER_NONE:
+    vnd->cipher = vio->cipher;
+    break;
+
+  case VND_CIPHER_XOR:            // XOR keys can be any size.
+    vnd->sc_keyctx  = malloc(vio->vnd_keylen, M_DEVBUF, M_WAITOK);
+    memcpy( vnd->sc_keyctx, key, vio->vnd_keylen);
+
+    vnd->vnd_keylen = vio->vnd_keylen;
+    vnd->cipher     = vio->cipher;
+    break;
+
+  case VND_CIPHER_BLOWFISH:       // Blowfish checks the key len, so any
+                                  // length up to: ((BF_ROUNDS+2)*4)) 
+
+    // Allocate a blowfish key
+    vnd->sc_keyctx  = malloc(sizeof(BF_KEY), M_DEVBUF, M_WAITOK);
+    vnd->vnd_keylen = sizeof(BF_KEY);
+
+    // Set the key
+    BF_set_key(vnd->sc_keyctx, vio->vnd_keylen, key);
+    
+    // Flag encryption
+    vnd->cipher = vio->cipher;
+    break;
+
+  }
+
+
+  // Clear the temp holder key we just copied in and free it
+  memset(key, 0, vio->vnd_keylen);
+  free((caddr_t)key, M_TEMP);
+
+
+  return 0;
+
+}
+
+
+
+void vnd_encode(struct vnd_softc *vnd, struct buf *bp)
+{
+  unsigned char *ptr;
+  int i, bsize;
+  u_char iv[8];      // hash in the block number
+  daddr_t off;
+
+  ptr = (unsigned char *) bp->b_data;
+
+#ifdef DEBUG
+  if (vnddebug & VDB_CIPHER)
+    printf("vnd_encode(%p, %lu, %u)\n", ptr, bp->b_bcount, bp->b_blkno);
+#endif
+
+  switch(vnd->cipher) {
+
+  case VND_CIPHER_NONE:
+    break;
+
+  case VND_CIPHER_XOR:
+    // If it just one long, skip the more complicated case.
+    if (vnd->vnd_keylen == 1) {
+
+      for (i = 0; i < bp->b_bcount; i++)
+	ptr[i] ^= ((u_char *)vnd->sc_keyctx)[0];
+
+    } else {
+      int key;
+
+      key = 0;
+      for (i = 0; i < bp->b_bcount; i++) {
+	ptr[i] ^= ((u_char *)vnd->sc_keyctx)[key++];
+	if (key >= vnd->vnd_keylen) key = 0;
+      }
+
+    }
+    break;
+
+  case VND_CIPHER_BLOWFISH:
+    bsize = dbtob(1);
+    off = bp->b_blkno;
+
+    for (i = 0; i < bp->b_bcount/bsize; i++) {
+
+      // Hash in the blknumber
+      memset(iv, 0, sizeof(iv));
+      memcpy(iv, (u_char *)&off, sizeof(bp->b_blkno));
+
+      //blf_ecb_encrypt(vnd->sc_keyctx, iv, sizeof(iv));
+      BF_encrypt((BF_LONG *)iv, vnd->sc_keyctx, 1);
+
+      // Process the block
+      //blf_cbc_encrypt(vnd->sc_keyctx, iv, ptr, bsize);
+      BF_cbc_encrypt(ptr, ptr, bsize, vnd->sc_keyctx, iv, 1);
+
+      ptr += bsize;
+      off++;
+    }
+    break;
+  }
+
+}
+
+
+
+
+void vnd_decode(struct vnd_softc *vnd, struct buf *bp)
+{
+  unsigned char *ptr;
+  int i, bsize;
+  u_char iv[8];      // hash in the block number
+  daddr_t off;
+
+  ptr = (unsigned char *) bp->b_data;
+
+#ifdef DEBUG
+  if (vnddebug & VDB_CIPHER)
+    printf("vnd_decode(%p, %lu, %u)\n", ptr, bp->b_bcount, bp->b_blkno);
+#endif
+
+  switch(vnd->cipher) {
+
+  case VND_CIPHER_NONE:
+    break;
+
+  case VND_CIPHER_XOR:
+    // If it just one long, skip the more complicated case.
+    if (vnd->vnd_keylen == 1) {
+
+      for (i = 0; i < bp->b_bcount; i++)
+	ptr[i] ^= ((u_char *)vnd->sc_keyctx)[0];
+
+    } else {
+      int key;
+
+      key = 0;
+      for (i = 0; i < bp->b_bcount; i++) {
+	ptr[i] ^= ((u_char *)vnd->sc_keyctx)[key++];
+	if (key >= vnd->vnd_keylen) key = 0;
+      }
+
+    }
+
+    break;
+
+  case VND_CIPHER_BLOWFISH:
+        
+    bsize = dbtob(1);
+    off = bp->b_blkno;
+
+    for (i = 0; i < bp->b_bcount/bsize; i++) {
+
+      // Hash in the blknumber
+      memset(iv, 0, sizeof(iv));
+      memcpy(iv, (u_char *)&off, sizeof(bp->b_blkno));
+
+      //blf_ecb_encrypt(vnd->sc_keyctx, iv, sizeof(iv));
+      BF_encrypt((BF_LONG *)iv, vnd->sc_keyctx, 1);
+
+      // Process the block
+      //blf_cbc_encrypt(vnd->sc_keyctx, iv, ptr, bsize);
+      BF_cbc_encrypt(ptr, ptr, bsize, vnd->sc_keyctx, iv, 0);
+
+      ptr += bsize;
+      off++;
+    }
+
+   break;
+  }
+
+}
+
+
+
+#endif
+
+
+
+
+
+
+
+
+
+
+
+
 void
 vndattach(num)
 	int num;
@@ -200,6 +441,7 @@
 
 	for (i = 0; i < numvnd; i++)
 		BUFQ_INIT(&vnd_softc[i].sc_tab);
+
 }
 
 int
@@ -217,6 +459,7 @@
 	if (vnddebug & VDB_FOLLOW)
 		printf("vndopen(0x%x, 0x%x, 0x%x, %p)\n", dev, flags, mode, p);
 #endif
+
 	if (unit >= numvnd)
 		return (ENXIO);
 	sc = &vnd_softc[unit];
@@ -528,6 +771,13 @@
 			    bp->b_flags, bp->b_data, bp->b_bcount);
 #endif
 
+
+#ifdef VND_CIPHER
+		if ((bp->b_flags & B_READ) == 0) { // WRITE?
+		  vnd_encode(vnd, bp);
+		}
+#endif
+
 		/* Instrumentation. */
 		disk_busy(&vnd->sc_dkdev);
 
@@ -571,6 +821,18 @@
 		vnx->vx_error = vbp->vb_buf.b_error;
 	}
 
+#ifdef VND_CIPHER
+
+	// If it is a block off disk - decode
+	// If it is a block we wrote, and encode above, decode for cache
+	// are there _any_ other circumstances why we might arrive here?
+	// If so, we need to wrap this in an 'if' to avoid that case.
+	vnd_decode(vnd, &vbp->vb_buf); 
+
+#endif
+
+
+
 	if (vbp->vb_buf.b_vp != NULLVP)
 		brelvp(&vbp->vb_buf);
 
@@ -615,6 +877,14 @@
 	splx(s);
 }
 
+
+
+
+
+
+
+
+
 /* ARGSUSED */
 int
 vndread(dev, uio, flags)
@@ -663,6 +933,7 @@
 		return (ENXIO);
 
 	return (physio(vndstrategy, NULL, dev, B_WRITE, minphys, uio));
+
 }
 
 /* ARGSUSED */
@@ -832,6 +1103,18 @@
 		 */
 		vnd->sc_size = geomsize;
 
+
+#ifdef VND_CIPHER
+
+		if ((error = vnd_setkey(vnd, vio)) != 0) {
+		  (void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
+		  vndunlock(vnd);
+		  return(error);
+		}
+		
+#endif
+
+
 		if ((error = vndsetcred(vnd, p->p_ucred)) != 0) {
 			(void) vn_close(nd.ni_vp, FREAD|FWRITE, p->p_ucred, p);
 			vndunlock(vnd);
@@ -968,6 +1251,7 @@
 		break;
 	}
 
+
 	case DIOCWLABEL:
 		if (*(int *)data != 0)
 			vnd->sc_flags |= VNF_WLABEL;
@@ -1092,6 +1376,18 @@
 	vnd->sc_vp = (struct vnode *)0;
 	vnd->sc_cred = (struct ucred *)0;
 	vnd->sc_size = 0;
+#ifdef VND_CIPHER
+	if ((vnd->vnd_keylen > 0) && vnd->sc_keyctx) {
+	  memset(vnd->sc_keyctx, 0, vnd->vnd_keylen);
+	  free((caddr_t)vnd->sc_keyctx, M_DEVBUF);
+	}
+
+	vnd->sc_keyctx  = NULL;
+	vnd->vnd_keylen = 0;
+	vnd->cipher     = VND_CIPHER_NONE;
+
+#endif
+
 }
 
 int
@@ -1265,3 +1561,6 @@
 		wakeup(sc);
 	}
 }
+
+
+
diff -u -r --exclude=arch/sparc/* --exclude=*~ --exclude=CVS ./dev/vndvar.h /mnt/src/sys/dev/vndvar.h
--- ./dev/vndvar.h	Tue Mar 21 12:19:50 2000
+++ /mnt/src/sys/dev/vndvar.h	Thu Nov  1 22:12:15 2001
@@ -80,6 +80,20 @@
 
 #include <sys/pool.h>
 
+
+
+
+// If you want encrypted filesystems, define this
+#define VND_CIPHER 
+
+
+
+
+#ifdef VND_CIPHER
+enum vnd_ciphers { VND_CIPHER_NONE, VND_CIPHER_XOR, VND_CIPHER_BLOWFISH };
+#endif
+
+
 /*
  * Vnode disk pseudo-geometry information.
  */
@@ -98,6 +112,11 @@
 	int		vnd_flags;	/* flags; see below */
 	struct vndgeom	vnd_geom;	/* geometry to emulate */
 	int		vnd_size;	/* (returned) size of disk */
+#ifdef VND_CIPHER
+        enum vnd_ciphers cipher;        
+        u_char  *vnd_key;
+        int     vnd_keylen;
+#endif
 };
 
 /* vnd_flags */
@@ -108,6 +127,7 @@
 struct vnode;
 struct ucred;
 
+
 /*
  * A vnode disk's state information.
  */
@@ -118,13 +138,19 @@
 	struct vnode	*sc_vp;		/* vnode */
 	struct ucred	*sc_cred;	/* credentials */
 	int		 sc_maxactive;	/* max # of active requests */
-	struct buf_queue sc_tab;	/* transfer queue */
+  struct buf_queue sc_tab;	/* transfer queue */
+  //struct buf sc_tab;	/* transfer queue */
 	int		 sc_active;	/* number of active transfers */
 	char		 sc_xname[8];	/* XXX external name */
 	struct disk	 sc_dkdev;	/* generic disk device info */
 	struct vndgeom	 sc_geom;	/* virtual geometry */
 	struct pool	 sc_vxpool;	/* vndxfer pool */
 	struct pool	 sc_vbpool;	/* vndbuf pool */
+#ifdef VND_CIPHER
+        enum vnd_ciphers cipher;        
+        int              vnd_keylen;    /* Used for only _some_ ciphers */
+	void		*sc_keyctx;	/* key context */
+#endif
 };
 #endif
 





---------------------------- cut here -------------------------




--- vnconfig.c	Sat Nov  3 00:13:00 2001
+++ /usr/home/lundman/vnconfig.c	Wed Sep 26 12:07:29 2001
@@ -1,4 +1,4 @@
-/*	$NetBSD: vnconfig.c,v 1.19 2000/03/20 13:20:28 jdolecek Exp $	*/
+/*	$NetBSD: vnconfig.c,v 1.20 2001/09/26 07:05:39 lukem Exp $	*/
 
 /*-
  * Copyright (c) 1997 The NetBSD Foundation, Inc.
@@ -81,7 +81,6 @@
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/mount.h>
-#include <sys/stat.h>
 #include <sys/buf.h>
 #include <sys/disklabel.h>
 #include <sys/disk.h>
@@ -104,25 +103,12 @@
 int	verbose = 0;
 char	*tabname;
 
-#ifdef VND_CIPHER
-char    *cipher;
-int     generate_key = 0;
-#endif
-
 int	config __P((char *, char *, char *, int));
 int	getgeom __P((struct vndgeom *, char *));
 int	main __P((int, char **));
 char   *rawdevice __P((char *));
 void	usage __P((void));
 
-#ifdef VND_CIPHER
-void    set_cipher __P((struct vnd_ioctl *));
-char   *new_key __P((int));
-char   *input_key __P((int *));
-int     base64_decode(char *, char *, int);
-void    base64_encode(const unsigned char *, size_t, unsigned char *);
-#endif
-
 int
 main(argc, argv)
 	int argc;
@@ -130,11 +116,7 @@
 {
 	int ch, rv, action = VND_CONFIG;
 
-#ifdef VND_CIPHER
-	while ((ch = getopt(argc, argv, "ct:uvC:N:")) != -1) {
-#else
 	while ((ch = getopt(argc, argv, "ct:uv")) != -1) {
-#endif
 		switch (ch) {
 		case 'c':
 			action = VND_CONFIG;
@@ -148,14 +130,6 @@
 		case 'v':
 			verbose = 1;
 			break;
-#ifdef VND_CIPHER
-		case 'C':
-                        cipher = optarg;
-			break;
-		case 'N':
-		        generate_key = atoi(optarg);
-			break;
-#endif
 		default:
 		case '?':
 			usage();
@@ -179,305 +153,6 @@
 	exit(rv);
 }
 
-
-
-
-#ifdef VND_CIPHER
-
-
-static const char enc[] =
-  "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-
-
-/*
- * Encode len bytes starting at clear using base64 encoding into encoded,
- * which should be at least ((len + 2) * 4 / 3 + 1) in size.
- */
-void
-base64_encode(clear, len, encoded)
-        const unsigned char  *clear;
-        size_t           len;
-        unsigned char        *encoded;
-{
-        static const char enc[] =
-            "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
-        char    *cp;
-        int      i;
-
-        cp = encoded;
-        for (i = 0; i < len; i += 3) {
-                *(cp++) = enc[((clear[i + 0] >> 2))];
-                *(cp++) = enc[((clear[i + 0] << 4) & 0x30)
-                            | ((clear[i + 1] >> 4) & 0x0f)];
-                *(cp++) = enc[((clear[i + 1] << 2) & 0x3c)
-                            | ((clear[i + 2] >> 6) & 0x03)];
-                *(cp++) = enc[((clear[i + 2]     ) & 0x3f)];
-        }
-        *cp = '\0';
-        while (i-- > len)
-                *(--cp) = '=';
-}
-
-
-
-
-
-
-//                      input         output     
-int base64_decode(char *encoded, char *plain, int size)
-{
-  char inalphabet[256], decoder[256];
-  int i, bits, c, char_count, errors = 0, incount = 0, outcount = 0;
-
-    for (i = (sizeof enc) - 1; i >= 0 ; i--) {
-        inalphabet[(int)enc[i]] = 1;
-        decoder[(int)enc[i]] = i;
-    }
-
-    char_count = 0;
-    bits = 0;
-
-    while (1) {
-
-      if (incount >= size) break;
-
-      c = encoded[incount++];
-      
-      if (c == '=')
-	break;
-      if (c > 255 || ! inalphabet[c])
-	continue;
-      bits += decoder[c];
-      char_count++;
-      if (char_count == 4) {
-	
-	plain[outcount++] = (bits >> 16);
-	plain[outcount++] = ((bits >> 8) & 0xff);
-	plain[outcount++] = (bits & 0xff);
-	bits = 0;
-	char_count = 0;
-      } else {
-	bits <<= 6;
-      }
-    }
-
-    if (c != '=') {
-      if (char_count) {
-	errx(1, "base64 encoding incomplete: at least %d bits truncated",
-	     ((4 - char_count) * 6));
-	errors++;
-      }
-    } else { /* c == '=' */
-      switch (char_count) {
-      case 1:
-	errx(1, "base64 encoding incomplete: at least 2 bits missing");
-	errors++;
-	break;
-      case 2:
-	plain[outcount++] = (bits >> 10);
-	break;
-      case 3:
-	plain[outcount++] = (bits >> 16);
-	plain[outcount++] = ((bits >> 8) & 0xff);
-	break;
-      }
-    }
-
-    return errors ? -1 : outcount;
-}
-
-
-
-
-
-
-
-
-
-
-
-
-void set_cipher(struct vnd_ioctl *vio)
-{
-
-  // Assuming we always have none.
-  if (!strcasecmp("none", cipher)) {
-
-    vio->cipher = VND_CIPHER_NONE;
-    return;
-
-#if defined VND_CIPHER_XOR
-  } else if (!strcasecmp("xor", cipher)) {
-
-    vio->cipher = VND_CIPHER_XOR;
-
-#endif
-#ifdef VND_CIPHER_BLOWFISH
-  } else if (!strcasecmp("blowfish", cipher)) {
-
-    vio->cipher = VND_CIPHER_BLOWFISH;
-
-#endif
-  } else {
-
-    errx(1, "unknown cipher type: '%s'", cipher);
-    return;  // NOT REACHED
-
-  }    
-
-  // If user wants us to generate a key - do so.
-  if (generate_key > 0) {
-
-    vio->vnd_key    = new_key(generate_key);
-    vio->vnd_keylen = generate_key;
-
-  } else {  // Ask for the key
-
-    vio->vnd_key    = input_key(&vio->vnd_keylen);
-    
-    if (!vio->vnd_key || (vio->vnd_keylen <= 0))
-      errx(1, "no key for cipher");
-    
-  }
-
-}
-
-char *new_key(int size)
-{
-  int fd, red, bytes;
-  char *result;
-  char *encoded;
-
-  // I deliberately do not clear this buffer
-  result = (char *) malloc(size);
-
-  if (!result)
-    errx(1, "unable to allocate memory");
-
-  printf("Generating %d bytes of random...\n", size);
-
-  fd = open("/dev/random", O_RDONLY);
-
-  if (fd < 0) {
-
-    warn("unable to open /dev/random");
-
-  } else {
-
-    for (red = 0; red < size; red += bytes) {
-
-      bytes = read(fd, &result[red], size - red);
-      if (bytes <= 0) break;
-      
-    }
-
-    if (red < size) warn("random read %d < %d required", red, size);
-
-    close(fd);
-
-  }
-
-  encoded = (char *) malloc(((size + 2) * 4 / 3 + 1)); 
-  if (!encoded) errx(1, "unable to allocate temporary memory:");
-
-
-  // Dump the key
-  base64_encode(result, size, encoded);
-
-  printf("--key encoding: base64\n");
-  for (bytes = 0; encoded[bytes] != '='; bytes++) {
-    
-    if (bytes && !(bytes % 75)) putchar('\n');
-    putchar( encoded[bytes] );
-
-  }
-  puts("=\n");
-
-#if 0
-  {
-    char test[1028];
-    printf("Testing decoder\n");
-    printf("%d\n", base64_decode(encoded, test, ((size + 2) * 4 / 3 + 1)));
-    printf("%d\n", memcmp(test, result, size));
-
-  }
-#endif 
-
-  memset(encoded, 0, ((size + 2) * 4 / 3 + 1));
-
-  free(encoded);
-
-  return result;
-
-}
-
-char *input_key(int *size)
-{
-  char *pass;
-  char *result = NULL;
-  int len = 0, slen;
-  char line[256];
-
-  pass = getpass("Enter key:");
-
-  if (!pass) return NULL;
-
-  // If the input is base64 - decode it.
-  if (!strcmp("--key encoding: base64", pass)) {
-
-    printf("Reading in base64 key...\n");
-
-    // fetch the input, until we get a line with '=' or EOF.
-    while(fgets(line, 256, stdin)) {
-      char *r;
-
-      if ((r = strchr(line, '\r'))) *r = 0;
-      if ((r = strchr(line, '\n'))) *r = 0;
-
-      slen = strlen(line); 
-
-      result = realloc(result, len + slen + 1);
-      
-      if (!result) errx(1, "unable to allocate memory:");
-
-      strcpy(&result[len], line);
-      
-      len += slen;
-
-      if (strchr(line, '=')) break;
-
-    }
-
-    slen = base64_decode(result, result, len);
-
-    if (slen <= 0)
-      errx(1, "unable to decode input key:");
-
-    printf("Successfully decoded key of %d bytes.\n", slen);
-    *size = slen;
-
-  } else {
-
-    result = strdup(pass);
-    *size = strlen(result);
-
-  }
-  
-
-  memset(pass, 0, strlen(pass));
-
-  return result;
-
-}
-
-
-#endif
-
-
-
-
-
-
 int
 config(dev, file, geom, action)
 	char *dev, *file, *geom;
@@ -499,7 +174,6 @@
 	rv = 0;			/* XXX */
 #endif
 
-
 	vndio.vnd_file = file;
 	if (geom != NULL) {
 		rv = getgeom(&vndio.vnd_geom, geom);
@@ -531,11 +205,6 @@
 	 * Configure the device
 	 */
 	if (action == VND_CONFIG) {
-
-#ifdef VND_CIPHER
-	  if (cipher) set_cipher(&vndio);
-#endif
-
 		rv = ioctl(fd, VNDIOCSET, &vndio);
 		if (rv)
 			warn("%s: VNDIOCSET", rdev);
@@ -551,15 +220,6 @@
 			printf("\n");
 		}
 
-#ifdef VND_CIPHER
-		// Destroy and free the key.
-		if (vndio.vnd_key && (vndio.vnd_keylen)) {
-		  memset(vndio.vnd_key, 0, vndio.vnd_keylen);
-		  free(vndio.vnd_key);
-		}
-#endif
-
-
 	}
 
 	(void) close(fd);
@@ -614,25 +274,10 @@
 void
 usage()
 {
-#ifdef VND_CIPHER
-	(void)fprintf(stderr, "%s%s",
-	    "usage: vnconfig [-c] [-t typename] [-v] [-C cipher] [-N len] ...\n"
-            "                special-file regular-file [geomspec]\n",
-	    "       vnconfig -u [-v] special-file\n");
-	(void)fprintf(stderr, "       supported ciphers: none "
-#ifdef VND_CIPHER_XOR
-		      "xor "
-#endif
-#ifdef VND_CIPHER_BLOWFISH
-		      "blowfish "
-#endif
-		      "\n");
-#else
+
 	(void)fprintf(stderr, "%s%s",
-	    "usage: vnconfig [-c] [-t typename] [-v]"
-                " special-file"
+	    "usage: vnconfig [-c] [-t typename] [-v] special-file"
 		" regular-file [geomspec]\n",
 	    "       vnconfig -u [-v] special-file\n");
-#endif
 	exit(1);
 }
>Release-Note:
>Audit-Trail:
>Unformatted: