Subject: kern/15255: Added crypt to CCD
To: None <gnats-bugs@gnats.netbsd.org>
From: Lord Lundman <lundman@netbsd.hotgen.com>
List: netbsd-bugs
Date: 01/15/2002 16:32:29
>Number:         15255
>Category:       kern
>Synopsis:       Feature Addition
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    kern-bug-people
>State:          open
>Class:          change-request
>Submitter-Id:   net
>Arrival-Date:   Tue Jan 15 08:33:01 PST 2002
>Closed-Date:
>Last-Modified:
>Originator:     Jorgen Lundman
>Release:        20/12/2001
>Organization:
	
>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
Also tested on Sparc

>Description:
    Added poor-man's encryption feature to 'ccd' devices. This includes
    patches to 'ccdconfig' to allow the configuration of it. It requires
    crypto/blowfish/ files, and 'files' has been updated to reflect this.
    This is a similar feature as added to 'vnd' but 'vnd' is unfortunately
    broken (plain vnd). patch run from /usr/src/. Note the 'ccdvar.h' file in
    sys/dev/ also require its changes to be applied to the 
    /usr/include/dev/vndvar.h version.


>How-To-Repeat:
     N/A

>Fix:
--- sys-orig/dev/ccd.c	Sat Aug 18 17:31:43 2001
+++ sys/dev/ccd.c	Tue Jan  1 04:09:01 2002
@@ -111,6 +111,12 @@
 
 #include <dev/ccdvar.h>
 
+
+#ifdef CCD_CIPHER
+#include <crypto/blowfish/blowfish.h>
+#endif
+
+
 #if defined(CCDDEBUG) && !defined(DEBUG)
 #define DEBUG
 #endif
@@ -121,6 +127,7 @@
 #define CCDB_IO		0x04
 #define CCDB_LABEL	0x08
 #define CCDB_VNODE	0x10
+#define CCDB_CIPHER 0x20
 int ccddebug = 0x00;
 #endif
 
@@ -170,6 +177,162 @@
 struct	ccd_softc *ccd_softc;
 int	numccd = 0;
 
+
+
+#ifdef CCD_CIPHER
+void ccd_encode(struct ccd_softc *, struct buf *, int);
+int  ccd_setkey(struct ccd_softc *, struct ccd_ioctl *);
+
+/*
+ * At ioctl configure time, take cipher variables and key to copyin
+ * and allocate buffer space. Also call ciphers appripriate set_key
+ * function, if any.
+ */
+int ccd_setkey(struct ccd_softc *ccd, struct ccd_ioctl *cio)
+{
+	char *key;
+	int error; 
+	
+	/* No cipher, return success */
+	if (cio->cipher == CCD_CIPHER_NONE) return 0; 
+	
+	/* We are to use a cipher, check we've been passed what we need */
+	if ((cio->ccd_keylen <= 0) ||
+		(cio->ccd_key == NULL))
+		return EINVAL;
+	
+	
+	
+	ccd->cipher     = CCD_CIPHER_NONE; /* Set it to none incase we fail. */
+	ccd->ccd_keylen = 0;
+	
+	
+	/* Allocate temp holder for the key */
+	key = malloc(cio->ccd_keylen, M_TEMP, M_WAITOK);
+	
+	/* Copy it into kernel space */
+	if ((error = copyin((caddr_t)cio->ccd_key, key,
+						cio->ccd_keylen)) != 0) {
+		return (error);
+	}
+	
+	
+	
+	switch(cio->cipher) {
+		
+	case CCD_CIPHER_NONE:
+		ccd->cipher = cio->cipher;
+		break;
+		
+	case CCD_CIPHER_XOR:            /* XOR keys can be any size. */
+		ccd->sc_keyctx  = malloc(cio->ccd_keylen, M_DEVBUF, M_WAITOK);
+		memcpy( ccd->sc_keyctx, key, cio->ccd_keylen);
+		
+		ccd->ccd_keylen = cio->ccd_keylen;
+		ccd->cipher     = cio->cipher;
+		break;
+		
+	case CCD_CIPHER_BLOWFISH:       /* Blowfish checks the key len, so any
+									 * length up to: ((BF_ROUNDS+2)*4)) */
+		
+		/* Allocate a blowfish key */
+		ccd->sc_keyctx  = malloc(sizeof(BF_KEY), M_DEVBUF, M_WAITOK);
+		ccd->ccd_keylen = sizeof(BF_KEY);
+		
+		/* Set the key */
+		BF_set_key(ccd->sc_keyctx, cio->ccd_keylen, key);
+		
+		/* Flag encryption */
+		ccd->cipher = cio->cipher;
+		break;
+		
+	}
+	
+	
+	/* Clear the temp holder key we just copied in and free it */
+	memset(key, 0, cio->ccd_keylen);
+	free((caddr_t)key, M_TEMP);
+	
+	
+	return 0;
+	
+}
+
+
+#define CCD_ENCRYPT 1
+#define CCD_DECRYPT 0
+
+/*
+ * Accept buffer to be encoded:
+ * Encrypt block against key and blocknumber
+ */
+void ccd_encode(struct ccd_softc *ccd, struct buf *bp, int encrypt)
+{
+    unsigned char *ptr;
+	int i, bsize;
+	u_char iv[8];     
+	daddr_t off;
+	
+	ptr = (unsigned char *) bp->b_data;
+	
+#ifdef DEBUG
+	if (ccddebug & CCDB_CIPHER)
+	    printf("ccd_%s(%p, %lu, %u)\n", 
+			   encrypt ? "encode" : "decode",
+			   ptr, bp->b_bcount, bp->b_blkno);
+#endif
+	
+	switch(ccd->cipher) {
+		
+	case CCD_CIPHER_NONE:
+	    break;
+
+	case CCD_CIPHER_XOR:
+		/* If it just one char in size, skip the more complicated case. */
+		if (ccd->ccd_keylen == 1) {
+			
+			for (i = 0; i < bp->b_bcount; i++)
+				ptr[i] ^= ((u_char *)ccd->sc_keyctx)[0];
+			
+		} else {
+			int key; 
+			
+			key = 0;
+			for (i = 0; i < bp->b_bcount; i++) {
+				ptr[i] ^= ((u_char *)ccd->sc_keyctx)[key++];
+				if (key >= ccd->ccd_keylen) 
+					key = 0;
+			}
+			
+		}
+		break;
+		
+	case CCD_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));
+			
+			BF_encrypt((BF_LONG *)iv, ccd->sc_keyctx, 1);
+			
+			/* Process the block */
+			BF_cbc_encrypt(ptr, ptr, bsize, ccd->sc_keyctx, iv, encrypt);
+			
+			ptr += bsize;
+			off++;
+		}
+		break;
+	}
+	
+}
+
+#endif // CCD_CIPHER
+
+
 /*
  * Called by main() during pseudo-device attachment.  All we need
  * to do is allocate enough space for devices to be configured later.
@@ -707,7 +870,22 @@
 		SIMPLEQ_REMOVE_HEAD(&cbufq, cbp, cb_q);
 		if ((cbp->cb_buf.b_flags & B_READ) == 0)
 			cbp->cb_buf.b_vp->v_numoutput++;
+
+#ifdef CCD_CIPHER
+
+		/* If this is a WRITE request - encrypt the block */
+
+		if ((cbp->cb_buf.b_flags & B_READ) == 0) {
+
+			ccd_encode(cs, &cbp->cb_buf, CCD_ENCRYPT);
+
+		}
+
+#endif
+
+
 		VOP_STRATEGY(&cbp->cb_buf);
+
 	}
 }
 
@@ -862,6 +1040,12 @@
 	}
 #endif
 
+#ifdef CCD_CIPHER
+
+	ccd_encode(cs, &cbp->cb_buf, CCD_DECRYPT);
+
+#endif
+
 	if (cbp->cb_buf.b_flags & B_ERROR) {
 		bp->b_flags |= B_ERROR;
 		bp->b_error = cbp->cb_buf.b_error ?
@@ -1093,6 +1277,16 @@
 		ccio->ccio_unit = unit;
 		ccio->ccio_size = cs->sc_size;
 
+
+#ifdef CCD_CIPHER
+		
+		if ((error = ccd_setkey(cs, ccio)) != 0) {
+			goto out;
+		}
+		
+#endif
+
+
 		/* Attach the disk. */
 		disk_attach(&cs->sc_dkdev);
 
@@ -1147,6 +1341,20 @@
 
 		/* Detatch the disk. */
 		disk_detach(&cs->sc_dkdev);
+
+#ifdef CCD_CIPHER
+		if ((cs->ccd_keylen > 0) && cs->sc_keyctx) {
+	    memset(cs->sc_keyctx, 0, cs->ccd_keylen);
+		free((caddr_t)cs->sc_keyctx, M_DEVBUF);
+	}
+
+	cs->sc_keyctx  = NULL;
+	cs->ccd_keylen = 0;
+	cs->cipher     = CCD_CIPHER_NONE;
+	
+#endif
+
+
 		break;
 
 	case DIOCGDINFO:

--- sbin-orig/ccdconfig/ccdconfig.c	Wed Oct 18 11:22:57 2000
+++ sbin/ccdconfig/ccdconfig.c	Tue Jan  1 04:11:50 2002
@@ -1,4 +1,4 @@
-/*	$NetBSD: ccdconfig.c,v 1.30.2.2 2000/10/18 00:39:43 tv Exp $	*/
+/*	$NetBSD: ccdconfig.c,v 1.34 2001/02/19 22:56:18 cgd Exp $	*/
 
 /*-
  * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
@@ -41,9 +41,16 @@
 __COPYRIGHT(
 "@(#) Copyright (c) 1996, 1997\
 	The NetBSD Foundation, Inc.  All rights reserved.");
-__RCSID("$NetBSD: ccdconfig.c,v 1.30.2.2 2000/10/18 00:39:43 tv Exp $");
+__RCSID("$NetBSD: ccdconfig.c,v 1.34 2001/02/19 22:56:18 cgd Exp $");
 #endif
 
+/*
+ * Added additional support for generating, and input of, keys for encryption
+ * Note that getpass() eats all input so it is not possible to paste an
+ * entire base64'ed key in one go, this is not desirable
+ * - Jorgen Lundman <lundman@lundman.net>
+ */
+
 #include <sys/param.h>
 #include <sys/ioctl.h>
 #include <sys/disklabel.h>
@@ -68,19 +75,23 @@
 
 #include "pathnames.h"
 
-extern	char *__progname;
-
 
 static	size_t lineno;
 static	gid_t egid;
 static	int verbose;
-static	char *ccdconf = _PATH_CCDCONF;
+static	const char *ccdconf = _PATH_CCDCONF;
 
 static	char *core;
 static	char *kernel;
 
+#ifdef CCD_CIPHER
+char    *cipher;
+int     generate_key = 0;
+#endif
+
+
 struct	flagval {
-	char	*fv_flag;
+	const char *fv_flag;
 	int	fv_val;
 } flagvaltab[] = {
 	{ "CCDF_UNIFORM",	CCDF_UNIFORM },
@@ -113,6 +124,14 @@
 static	char *resolve_ccdname __P((char *));
 static	void usage __P((void));
 
+#ifdef CCD_CIPHER
+void    set_cipher __P((struct ccd_ioctl *));
+char   *new_key __P((int));
+char   *input_key __P((int *));
+int     base64_decode __P((char *, char *, int));
+void    base64_encode __P((const unsigned char *, size_t, unsigned char *));
+#endif
+
 int
 main(argc, argv)
 	int argc;
@@ -122,7 +141,12 @@
 
 	egid = getegid();
 	setegid(getgid());
+#ifdef CCD_CIPHER
+	while ((ch = getopt(argc, argv, "cCf:gM:N:uUvX:S:")) != -1) {
+#else
 	while ((ch = getopt(argc, argv, "cCf:gM:N:uUv")) != -1) {
+#endif
+
 		switch (ch) {
 		case 'c':
 			action = CCD_CONFIG;
@@ -164,6 +188,15 @@
 			verbose = 1;
 			break;
 
+#ifdef CCD_CIPHER
+		case 'X':
+		    cipher = optarg;
+			break;
+		case 'S':
+		    generate_key = atoi(optarg);
+			break;
+#endif
+
 		default:
 			usage();
 		}
@@ -204,6 +237,341 @@
 	/* NOTREACHED */
 }
 
+
+
+#ifdef CCD_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.
+ * This was lifted from usr/bin/ftp/fetch.c - notice the change from
+ * char * to unsigned char * as it was encoding incorrectly (negative index)
+ * - Lundy
+ */
+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) = '=';
+}
+
+
+
+
+
+/*
+ * Take a base64 encoded buffer, and decode it into to plain original format
+ * Size is size of encoded buffer, 'plain' should contain enough space
+ * to hold the result. ((size - 1) * 3 / 4 - 1)
+ */
+int base64_decode(char *encoded, char *plain, int size)
+{
+    char inalphabet[256], decoder[256];
+	int i, bits, c, char_count, errors, incount, outcount;
+
+	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;
+}
+
+
+
+
+
+
+
+
+
+/*
+ * Fill in the required cipher entities in struct ccd_ioctl to pass to
+ * the kernel, as specified by command arguments
+ */
+void set_cipher(struct ccd_ioctl *vio)
+{
+
+    /* Assuming we always have 'none'.*/
+    if (!strcasecmp("none", cipher)) {
+
+	    vio->cipher = CCD_CIPHER_NONE;
+		return;
+
+#if defined CCD_CIPHER_XOR
+	} else if (!strcasecmp("xor", cipher)) {
+
+	    vio->cipher = CCD_CIPHER_XOR;
+
+#endif
+#ifdef CCD_CIPHER_BLOWFISH
+	} else if (!strcasecmp("blowfish", cipher)) {
+
+	    vio->cipher = CCD_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->ccd_key    = new_key(generate_key);
+		vio->ccd_keylen = generate_key;
+
+	} else {  /* Ask for the key from input */
+	  
+	    vio->ccd_key    = input_key(&vio->ccd_keylen);
+    
+		if (!vio->ccd_key || (vio->ccd_keylen <= 0))
+		    errx(1, "no key for cipher");
+    
+	}
+
+}
+
+
+/*
+ * Generate a new key of 'size' bytes. This function uses
+ * /dev/random which probably is not sufficiently stirred (comments?)
+ *
+ */
+char *new_key(int size)
+{
+    int fd, red, bytes;
+	char *result;
+	char *encoded;
+	
+	/*
+	 * I deliberately do not clear this buffer, should
+	 * /dev/random fail, perhaps there is some garbage in this
+	 * buffer (or not)
+	 */
+	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");
+
+	/* Clear the temporary space holder */
+	memset(encoded, 0, ((size + 2) * 4 / 3 + 1));
+	
+	free(encoded);
+	
+	return result;
+	
+}
+
+
+/*
+ * Ask for key from input, using standard password: functions.
+ * Note that if the key is that of "--key encoding" we dismiss
+ * input from getpass() and continue parsing until we hit EOF or
+ * '=' (end of base64).
+ */
+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 {
+	
+	    /* Use input from getpass() */
+	    result = strdup(pass);
+		*size = strlen(result);
+
+	}
+	
+	
+	memset(pass, 0, strlen(pass));
+
+	return result;
+	
+}
+
+
+#endif
+
+
+
+
+
+
+
 static int
 do_single(argc, argv, action)
 	int argc;
@@ -299,11 +667,27 @@
 	ccio.ccio_ileave = ileave;
 	ccio.ccio_flags = flags;
 
+#ifdef CCD_CIPHER
+	if (cipher) 
+		set_cipher(&ccio);
+#endif
+
+
 	if (do_io(ccd, CCDIOCSET, &ccio)) {
 		free(disks);
 		return (1);
 	}
 
+#ifdef CCD_CIPHER
+	/* Destroy and free the key. */
+	if (ccio.ccd_key && (ccio.ccd_keylen)) {
+		memset(ccio.ccd_key, 0, ccio.ccd_keylen);
+		free(ccio.ccd_key);
+	}
+#endif
+
+
+
 	if (verbose) {
 		printf("ccd%d: %d components ", ccio.ccio_unit,
 		    ccio.ccio_ndisks);
@@ -470,13 +854,14 @@
 	struct ccd_ioctl *cciop;
 {
 	int fd;
-	char *cp;
+	const char *cp;
 
 	if ((fd = open(path, O_RDWR, 0640)) < 0) {
 		warn("open: %s", path);
 		return (1);
 	}
 
+
 	if (ioctl(fd, cmd, cciop) < 0) {
 		switch (cmd) {
 		case CCDIOCSET:
@@ -721,13 +1106,30 @@
 static void
 usage()
 {
+	//const char *progname = getprogname();
+	const char *progname = "ccdconfig";
 
-	fprintf(stderr, "usage: %s [-cv] ccd ileave [flags] %s\n", __progname,
-	    "dev [...]");
-	fprintf(stderr, "       %s -C [-v] [-f config_file]\n", __progname);
-	fprintf(stderr, "       %s -u [-v] ccd [...]\n", __progname);
-	fprintf(stderr, "       %s -U [-v] [-f config_file]\n", __progname);
-	fprintf(stderr, "       %s -g [-M core] [-N system] %s\n", __progname,
-	    "[ccd [...]]");
+	fprintf(stderr, "usage: %s [-cv] ccd ileave [flags] dev [...]\n",
+	    progname);
+	fprintf(stderr, "       %s -C [-v] [-f config_file]\n", progname);
+	fprintf(stderr, "       %s -u [-v] ccd [...]\n", progname);
+	fprintf(stderr, "       %s -U [-v] [-f config_file]\n", progname);
+	fprintf(stderr, "       %s -g [-M core] [-N system] [ccd [...]]\n",
+	    progname);
+
+#ifdef CCD_CIPHER
+	fprintf(stderr, "       %s [-X cipher] [-S len] ...\n",
+	    progname);
+	fprintf(stderr, 
+			"       supported ciphers: none "
+#ifdef CCD_CIPHER_XOR
+			"xor "
+#endif
+#ifdef CCD_CIPHER_BLOWFISH
+			"blowfish "
+#endif
+			"\n");
+
+#endif
 	exit(1);
 }

--- sys-orig/dev/ccdvar.h	Sat Aug 18 17:31:45 2001
+++ sys/dev/ccdvar.h	Tue Jan  1 04:09:05 2002
@@ -90,6 +90,19 @@
  *	Moffett Field, CA 94035
  */
 
+#define CCD_CIPHER
+
+
+#ifdef CCD_CIPHER
+
+#define CCD_CIPHER_NONE      0  /* Must be 0 */
+#define CCD_CIPHER_XOR       1
+#define CCD_CIPHER_BLOWFISH  2
+
+#endif
+
+
+
 /*
  * This structure is used to configure a ccd via ioctl(2).
  */
@@ -100,6 +113,11 @@
 	int	ccio_flags;		/* see sc_flags below */
 	int	ccio_unit;		/* unit number: use varies */
 	size_t	ccio_size;		/* (returned) size of ccd */
+#ifdef CCD_CIPHER
+    int             cipher;        
+    u_char         *ccd_key;
+    int             ccd_keylen;
+#endif
 };
 
 /*
@@ -174,6 +192,11 @@
 	char		 sc_xname[8];		/* XXX external name */
 	struct disk	 sc_dkdev;		/* generic disk device info */
 	struct lock	 sc_lock;		/* lock on this structure */
+#ifdef CCD_CIPHER
+    int                  cipher;    /* cipher type to use */        
+    int                  ccd_keylen;/* Length of key - for memset at clear */
+	void		        *sc_keyctx;	/* key context */
+#endif
 };
 
 /* sc_flags */

--- sys-orig/conf/files	Sat Oct 27 15:53:56 2001
+++ sys/conf/files	Tue Jan  1 04:10:35 2002
@@ -573,8 +573,9 @@
 file crypto/arc4/arc4.c			wlan
 file crypto/des/des_ecb.c		ipsec & ipsec_esp
 file crypto/des/des_setkey.c		ipsec & ipsec_esp
-file crypto/blowfish/bf_enc.c		ipsec & ipsec_esp
-file crypto/blowfish/bf_skey.c		ipsec & ipsec_esp
+file crypto/blowfish/bf_enc.c		ipsec & ipsec_esp | ccd
+file crypto/blowfish/bf_cbc.c		ccd
+file crypto/blowfish/bf_skey.c		ipsec & ipsec_esp | ccd
 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


>Release-Note:
>Audit-Trail:
>Unformatted: