Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src -in the descriptor for encryption xforms, split the "blocksi...



details:   https://anonhg.NetBSD.org/src/rev/60f3f9b63cba
branches:  trunk
changeset: 765241:60f3f9b63cba
user:      drochner <drochner%NetBSD.org@localhost>
date:      Mon May 23 13:46:54 2011 +0000

description:
-in the descriptor for encryption xforms, split the "blocksize" field
 into "blocksize" and "IV size"
-add an "reinit" function pointer which, if set, means that the xform
 does its IV handling itself and doesn't want the default CBC handling
 by the framework (poor name, but left that way to avoid unecessary
 differences)
This syncs with Open/FreeBSD, purpose is to allow non-CBC transforms.
Refer to ivsize instead of blocksize where appropriate.
(At this point, blocksize and ivsize are identical.)

diffstat:

 share/man/man9/opencrypto.9       |   4 +-
 sys/netipsec/xform_esp.c          |  18 +++------
 sys/opencrypto/cryptodev.c        |  32 ++++++++++-------
 sys/opencrypto/cryptosoft.c       |  70 ++++++++++++++++++++++++++++++++------
 sys/opencrypto/cryptosoft_xform.c |  24 +++++++++---
 sys/opencrypto/xform.c            |  22 ++++++------
 sys/opencrypto/xform.h            |   4 +-
 7 files changed, 114 insertions(+), 60 deletions(-)

diffs (truncated from 516 to 300 lines):

diff -r 50221f5feb00 -r 60f3f9b63cba share/man/man9/opencrypto.9
--- a/share/man/man9/opencrypto.9       Mon May 23 06:50:17 2011 +0000
+++ b/share/man/man9/opencrypto.9       Mon May 23 13:46:54 2011 +0000
@@ -1,5 +1,5 @@
 .\"    $OpenBSD: crypto.9,v 1.25 2003/07/11 13:47:41 jmc Exp $
-.\"    $NetBSD: opencrypto.9,v 1.10 2010/01/22 10:28:08 wiz Exp $
+.\"    $NetBSD: opencrypto.9,v 1.11 2011/05/23 13:46:54 drochner Exp $
 .\"
 .\" The author of this man page is Angelos D. Keromytis (angelos%cis.upenn.edu@localhost)
 .\"
@@ -338,8 +338,6 @@
 Otherwise, the IV used to encrypt the packet will be written
 at the location pointed to by
 .Fa crd_inject .
-The IV length is assumed to be equal to the blocksize of the
-encryption algorithm.
 Some applications that do special
 .Dq IV cooking ,
 such as the half-IV mode in
diff -r 50221f5feb00 -r 60f3f9b63cba sys/netipsec/xform_esp.c
--- a/sys/netipsec/xform_esp.c  Mon May 23 06:50:17 2011 +0000
+++ b/sys/netipsec/xform_esp.c  Mon May 23 13:46:54 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: xform_esp.c,v 1.34 2011/05/06 21:48:46 drochner Exp $  */
+/*     $NetBSD: xform_esp.c,v 1.35 2011/05/23 13:46:54 drochner Exp $  */
 /*     $FreeBSD: src/sys/netipsec/xform_esp.c,v 1.2.2.1 2003/01/24 05:11:36 sam Exp $  */
 /*     $OpenBSD: ip_esp.c,v 1.69 2001/06/26 06:18:59 angelos Exp $ */
 
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.34 2011/05/06 21:48:46 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: xform_esp.c,v 1.35 2011/05/23 13:46:54 drochner Exp $");
 
 #include "opt_inet.h"
 #ifdef __FreeBSD__
@@ -149,7 +149,7 @@
                        size = sizeof (struct esp);
                else
                        size = sizeof (struct newesp);
-               size += sav->tdb_encalgxform->blocksize + 9;
+               size += sav->tdb_encalgxform->ivsize + 9;
                /*XXX need alg check???*/
                if (sav->tdb_authalgxform != NULL && sav->replay)
                        size += ah_hdrsiz(sav);
@@ -202,13 +202,7 @@
                return EINVAL;
        }
 
-       /*
-        * NB: The null xform needs a non-zero blocksize to keep the
-        *      crypto code happy but if we use it to set ivlen then
-        *      the ESP header will be processed incorrectly.  The
-        *      compromise is to force it to zero here.
-        */
-       sav->ivlen = (txform == &enc_xform_null ? 0 : txform->blocksize);
+       sav->ivlen = txform->ivsize;
        sav->iv = malloc(sav->ivlen, M_SECA, M_WAITOK);
        if (sav->iv == NULL) {
                DPRINTF(("esp_init: no memory for IV\n"));
@@ -1039,8 +1033,8 @@
        espstat_percpu = percpu_alloc(sizeof(uint64_t) * ESP_NSTATS);
 
 #define        MAXIV(xform)                                    \
-       if (xform.blocksize > esp_max_ivlen)            \
-               esp_max_ivlen = xform.blocksize         \
+       if (xform.ivsize > esp_max_ivlen)               \
+               esp_max_ivlen = xform.ivsize            \
 
        esp_max_ivlen = 0;
        MAXIV(enc_xform_des);           /* SADB_EALG_DESCBC */
diff -r 50221f5feb00 -r 60f3f9b63cba sys/opencrypto/cryptodev.c
--- a/sys/opencrypto/cryptodev.c        Mon May 23 06:50:17 2011 +0000
+++ b/sys/opencrypto/cryptodev.c        Mon May 23 13:46:54 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cryptodev.c,v 1.57 2011/05/16 10:27:49 drochner Exp $ */
+/*     $NetBSD: cryptodev.c,v 1.58 2011/05/23 13:46:54 drochner Exp $ */
 /*     $FreeBSD: src/sys/opencrypto/cryptodev.c,v 1.4.2.4 2003/06/03 00:09:02 sam Exp $        */
 /*     $OpenBSD: cryptodev.c,v 1.53 2002/07/10 22:21:30 mickey Exp $   */
 
@@ -64,7 +64,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.57 2011/05/16 10:27:49 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cryptodev.c,v 1.58 2011/05/23 13:46:54 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -428,7 +428,10 @@
                return E2BIG;
 
        if (cse->txform) {
-               if (cop->len == 0 || (cop->len % cse->txform->blocksize) != 0)
+               if (cop->len < cse->txform->blocksize
+                   + (cop->iv ? 0 : cse->txform->ivsize) ||
+                   (cop->len - (cop->iv ? 0 : cse->txform->ivsize))
+                   % cse->txform->blocksize != 0)
                        return EINVAL;
        }
 
@@ -582,9 +585,9 @@
                        goto bail;
                }
                if ((error = copyin(cop->iv, cse->tmp_iv,
-                   cse->txform->blocksize)))
+                   cse->txform->ivsize)))
                        goto bail;
-               (void)memcpy(crde->crd_iv, cse->tmp_iv, cse->txform->blocksize);
+               (void)memcpy(crde->crd_iv, cse->tmp_iv, cse->txform->ivsize);
                crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
                crde->crd_skip = 0;
        } else if (crde) {
@@ -592,8 +595,8 @@
                        crde->crd_skip = 0;
                } else {
                        crde->crd_flags |= CRD_F_IV_PRESENT;
-                       crde->crd_skip = cse->txform->blocksize;
-                       crde->crd_len -= cse->txform->blocksize;
+                       crde->crd_skip = cse->txform->ivsize;
+                       crde->crd_len -= cse->txform->ivsize;
                }
        }
 
@@ -1125,8 +1128,11 @@
                        continue;
                }
                if (cse->txform) {
-                       if (cnop[req].len == 0 || 
-                           (cnop[req].len % cse->txform->blocksize) != 0) { 
+                       if (cnop[req].len < cse->txform->blocksize -
+                           (cnop[req].iv ? 0 : cse->txform->ivsize) ||
+                           (cnop[req].len -
+                            (cnop[req].iv ? 0 : cse->txform->ivsize))
+                           % cse->txform->blocksize) {
                                cnop[req].status = EINVAL;
                                continue;
                        }
@@ -1272,12 +1278,12 @@
                                goto bail;
                        }
                        if ((error = copyin(cnop[req].iv, crp->tmp_iv,
-                           cse->txform->blocksize))) {
+                           cse->txform->ivsize))) {
                                cnop[req].status = EINVAL;
                                goto bail;
                        }
                        (void)memcpy(crde->crd_iv, crp->tmp_iv,
-                           cse->txform->blocksize);
+                           cse->txform->ivsize);
                        crde->crd_flags |= CRD_F_IV_EXPLICIT | CRD_F_IV_PRESENT;
                        crde->crd_skip = 0;
                } else if (crde) {
@@ -1285,8 +1291,8 @@
                                crde->crd_skip = 0;
                        } else {
                                crde->crd_flags |= CRD_F_IV_PRESENT;
-                               crde->crd_skip = cse->txform->blocksize;
-                               crde->crd_len -= cse->txform->blocksize;
+                               crde->crd_skip = cse->txform->ivsize;
+                               crde->crd_len -= cse->txform->ivsize;
                        }
                }
        
diff -r 50221f5feb00 -r 60f3f9b63cba sys/opencrypto/cryptosoft.c
--- a/sys/opencrypto/cryptosoft.c       Mon May 23 06:50:17 2011 +0000
+++ b/sys/opencrypto/cryptosoft.c       Mon May 23 13:46:54 2011 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: cryptosoft.c,v 1.31 2011/05/21 10:04:03 drochner Exp $ */
+/*     $NetBSD: cryptosoft.c,v 1.32 2011/05/23 13:46:54 drochner Exp $ */
 /*     $FreeBSD: src/sys/opencrypto/cryptosoft.c,v 1.2.2.1 2002/11/21 23:34:23 sam Exp $       */
 /*     $OpenBSD: cryptosoft.c,v 1.35 2002/04/26 08:43:50 deraadt Exp $ */
 
@@ -24,7 +24,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.31 2011/05/21 10:04:03 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: cryptosoft.c,v 1.32 2011/05/23 13:46:54 drochner Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -77,11 +77,13 @@
        unsigned char iv[EALG_MAX_BLOCK_LEN], blk[EALG_MAX_BLOCK_LEN], *idat;
        unsigned char *ivp, piv[EALG_MAX_BLOCK_LEN];
        const struct swcr_enc_xform *exf;
-       int i, k, j, blks;
+       int i, k, j, blks, ivlen;
        int count, ind;
 
        exf = sw->sw_exf;
        blks = exf->enc_xform->blocksize;
+       ivlen = exf->enc_xform->ivsize;
+       KASSERT(exf->reinit ? ivlen <= blks : ivlen == blks);
 
        /* Check for non-padded data */
        if (crd->crd_len % blks)
@@ -91,7 +93,7 @@
        if (crd->crd_flags & CRD_F_ENCRYPT) {
                /* IV explicitly provided ? */
                if (crd->crd_flags & CRD_F_IV_EXPLICIT)
-                       memcpy(iv, crd->crd_iv, blks);
+                       memcpy(iv, crd->crd_iv, ivlen);
                else {
                        /* Get random IV */
                        for (i = 0;
@@ -116,23 +118,35 @@
 
                /* Do we need to write the IV */
                if (!(crd->crd_flags & CRD_F_IV_PRESENT)) {
-                       COPYBACK(outtype, buf, crd->crd_inject, blks, iv);
+                       COPYBACK(outtype, buf, crd->crd_inject, ivlen, iv);
                }
 
        } else {        /* Decryption */
                        /* IV explicitly provided ? */
                if (crd->crd_flags & CRD_F_IV_EXPLICIT)
-                       memcpy(iv, crd->crd_iv, blks);
+                       memcpy(iv, crd->crd_iv, ivlen);
                else {
                        /* Get IV off buf */
-                       COPYDATA(outtype, buf, crd->crd_inject, blks, iv);
+                       COPYDATA(outtype, buf, crd->crd_inject, ivlen, iv);
                }
        }
 
        ivp = iv;
 
+       if (exf->reinit)
+               exf->reinit(sw->sw_kschedule, iv);
+
        if (outtype == CRYPTO_BUF_CONTIG) {
-               if (crd->crd_flags & CRD_F_ENCRYPT) {
+               if (exf->reinit) {
+                       for (i = crd->crd_skip;
+                            i < crd->crd_skip + crd->crd_len; i += blks) {
+                               if (crd->crd_flags & CRD_F_ENCRYPT) {
+                                       exf->encrypt(sw->sw_kschedule, buf + i);
+                               } else {
+                                       exf->decrypt(sw->sw_kschedule, buf + i);
+                               }
+                       }
+               } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                        for (i = crd->crd_skip;
                            i < crd->crd_skip + crd->crd_len; i += blks) {
                                /* XOR with the IV/previous block, as appropriate. */
@@ -183,7 +197,15 @@
                                m_copydata(m, k, blks, blk);
 
                                /* Actual encryption/decryption */
-                               if (crd->crd_flags & CRD_F_ENCRYPT) {
+                               if (exf->reinit) {
+                                       if (crd->crd_flags & CRD_F_ENCRYPT) {
+                                               exf->encrypt(sw->sw_kschedule,
+                                                            blk);
+                                       } else {
+                                               exf->decrypt(sw->sw_kschedule,
+                                                            blk);
+                                       }
+                               } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                                        /* XOR with previous block */
                                        for (j = 0; j < blks; j++)
                                                blk[j] ^= ivp[j];
@@ -253,7 +275,15 @@
                        idat = mtod(m, unsigned char *) + k;
 
                        while (m->m_len >= k + blks && i > 0) {
-                               if (crd->crd_flags & CRD_F_ENCRYPT) {
+                               if (exf->reinit) {
+                                       if (crd->crd_flags & CRD_F_ENCRYPT) {
+                                               exf->encrypt(sw->sw_kschedule,
+                                                            idat);
+                                       } else {
+                                               exf->decrypt(sw->sw_kschedule,
+                                                            idat);
+                                       }
+                               } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                                        /* XOR with previous block/IV */
                                        for (j = 0; j < blks; j++)
                                                idat[j] ^= ivp[j];
@@ -310,7 +340,15 @@
                                cuio_copydata(uio, k, blks, blk);
 
                                /* Actual encryption/decryption */
-                               if (crd->crd_flags & CRD_F_ENCRYPT) {
+                               if (exf->reinit) {
+                                       if (crd->crd_flags & CRD_F_ENCRYPT) {
+                                               exf->encrypt(sw->sw_kschedule,
+                                                            blk);
+                                       } else {
+                                               exf->decrypt(sw->sw_kschedule,
+                                                            blk);
+                                       }
+                               } else if (crd->crd_flags & CRD_F_ENCRYPT) {
                                        /* XOR with previous block */
                                        for (j = 0; j < blks; j++)
                                                blk[j] ^= ivp[j];
@@ -371,7 +409,15 @@
 



Home | Main Index | Thread Index | Old Index