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: