update OCF framework to version 20100325
[openwrt/openwrt.git] / target / linux / generic-2.6 / files / crypto / ocf / cryptodev.c
index 13d57a11fd7e81fd47410b0d1c96856ec680e816..87a4c379d42208730dcaa1634edcb9e7110124d0 100644 (file)
@@ -1,8 +1,8 @@
 /*     $OpenBSD: cryptodev.c,v 1.52 2002/06/19 07:22:46 deraadt Exp $  */
 
 /*-
- * Linux port done by David McCullough <david_mccullough@securecomputing.com>
- * Copyright (C) 2006-2007 David McCullough
+ * Linux port done by David McCullough <david_mccullough@mcafee.com>
+ * Copyright (C) 2006-2010 David McCullough
  * Copyright (C) 2004-2005 Intel Corporation.
  * The license and original author are listed below.
  *
@@ -77,6 +77,7 @@ struct csession_info {
        u_int16_t       keysize;
        /* u_int16_t    hashsize;  */
        u_int16_t       authsize;
+       u_int16_t       authkey;
        /* u_int16_t    ctxsize; */
 };
 
@@ -197,7 +198,7 @@ cryptodev_op(struct csession *cse, struct crypt_op *cop)
 
        if (cse->uio.uio_iov[0].iov_base == NULL) {
                dprintk("%s: iov_base kmalloc(%d) failed\n", __FUNCTION__,
-                               cse->uio.uio_iov[0].iov_len);
+                               (int)cse->uio.uio_iov[0].iov_len);
                return (ENOMEM);
        }
 
@@ -208,18 +209,22 @@ cryptodev_op(struct csession *cse, struct crypt_op *cop)
                goto bail;
        }
 
-       if (cse->info.authsize) {
-               crda = crp->crp_desc;
-               if (cse->info.blocksize)
-                       crde = crda->crd_next;
-       } else {
-               if (cse->info.blocksize)
+       if (cse->info.authsize && cse->info.blocksize) {
+               if (cop->op == COP_ENCRYPT) {
                        crde = crp->crp_desc;
-               else {
-                       dprintk("%s: bad request\n", __FUNCTION__);
-                       error = EINVAL;
-                       goto bail;
+                       crda = crde->crd_next;
+               } else {
+                       crda = crp->crp_desc;
+                       crde = crda->crd_next;
                }
+       } else if (cse->info.authsize) {
+               crda = crp->crp_desc;
+       } else if (cse->info.blocksize) {
+               crde = crp->crp_desc;
+       } else {
+               dprintk("%s: bad request\n", __FUNCTION__);
+               error = EINVAL;
+               goto bail;
        }
 
        if ((error = copy_from_user(cse->uio.uio_iov[0].iov_base, cop->src,
@@ -300,28 +305,31 @@ cryptodev_op(struct csession *cse, struct crypt_op *cop)
         * entry and the crypto_done callback into us.
         */
        error = crypto_dispatch(crp);
-       if (error == 0) {
-               dprintk("%s about to WAIT\n", __FUNCTION__);
+       if (error) {
+               dprintk("%s error in crypto_dispatch\n", __FUNCTION__);
+               goto bail;
+       }
+
+       dprintk("%s about to WAIT\n", __FUNCTION__);
+       /*
+        * we really need to wait for driver to complete to maintain
+        * state,  luckily interrupts will be remembered
+        */
+       do {
+               error = wait_event_interruptible(crp->crp_waitq,
+                               ((crp->crp_flags & CRYPTO_F_DONE) != 0));
                /*
-                * we really need to wait for driver to complete to maintain
-                * state,  luckily interrupts will be remembered
+                * we can't break out of this loop or we will leave behind
+                * a huge mess,  however,  staying here means if your driver
+                * is broken user applications can hang and not be killed.
+                * The solution,  fix your driver :-)
                 */
-               do {
-                       error = wait_event_interruptible(crp->crp_waitq,
-                                       ((crp->crp_flags & CRYPTO_F_DONE) != 0));
-                       /*
-                        * we can't break out of this loop or we will leave behind
-                        * a huge mess,  however,  staying here means if your driver
-                        * is broken user applications can hang and not be killed.
-                        * The solution,  fix your driver :-)
-                        */
-                       if (error) {
-                               schedule();
-                               error = 0;
-                       }
-               } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
-               dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
-       }
+               if (error) {
+                       schedule();
+                       error = 0;
+               }
+       } while ((crp->crp_flags & CRYPTO_F_DONE) == 0);
+       dprintk("%s finished WAITING error=%d\n", __FUNCTION__, error);
 
        if (crp->crp_etype != 0) {
                error = crp->crp_etype;
@@ -625,7 +633,7 @@ cryptodev_ioctl(
        struct crypt_kop kop;
        struct crypt_find_op fop;
        u_int64_t sid;
-       u_int32_t ses;
+       u_int32_t ses = 0;
        int feat, fd, error = 0, crid;
        mm_segment_t fs;
 
@@ -744,21 +752,27 @@ cryptodev_ioctl(
                        break;
                case CRYPTO_MD5_HMAC:
                        info.authsize = MD5_HASH_LEN;
+                       info.authkey = 16;
                        break;
                case CRYPTO_SHA1_HMAC:
                        info.authsize = SHA1_HASH_LEN;
+                       info.authkey = 20;
                        break;
                case CRYPTO_SHA2_256_HMAC:
                        info.authsize = SHA2_256_HASH_LEN;
+                       info.authkey = 32;
                        break;
                case CRYPTO_SHA2_384_HMAC:
                        info.authsize = SHA2_384_HASH_LEN;
+                       info.authkey = 48;
                        break;
                case CRYPTO_SHA2_512_HMAC:
                        info.authsize = SHA2_512_HASH_LEN;
+                       info.authkey = 64;
                        break;
                case CRYPTO_RIPEMD160_HMAC:
                        info.authsize = RIPEMD160_HASH_LEN;
+                       info.authkey = 20;
                        break;
                default:
                        dprintk("%s(%s) - bad mac\n", __FUNCTION__, CIOCGSESSSTR);
@@ -790,10 +804,9 @@ cryptodev_ioctl(
                if (info.authsize) {
                        cria.cri_alg = sop.mac;
                        cria.cri_klen = sop.mackeylen * 8;
-                       if ((info.maxkey && sop.mackeylen > info.maxkey) ||
-                                       sop.keylen < info.minkey) {
-                               dprintk("%s(%s) - mackeylen %d\n", __FUNCTION__, CIOCGSESSSTR,
-                                               sop.mackeylen);
+                       if (info.authkey && sop.mackeylen != info.authkey) {
+                               dprintk("%s(%s) - mackeylen %d != %d\n", __FUNCTION__,
+                                               CIOCGSESSSTR, sop.mackeylen, info.authkey);
                                error = EINVAL;
                                goto bail;
                        }
@@ -1044,5 +1057,5 @@ module_init(cryptodev_init);
 module_exit(cryptodev_exit);
 
 MODULE_LICENSE("BSD");
-MODULE_AUTHOR("David McCullough <david_mccullough@securecomputing.com>");
+MODULE_AUTHOR("David McCullough <david_mccullough@mcafee.com>");
 MODULE_DESCRIPTION("Cryptodev (user interface to OCF)");