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: