Author: kib
Date: Thu Jul 29 20:42:20 2010
New Revision: 210631
URL: http://svn.freebsd.org/changeset/base/210631

Log:
  Add compat32 shims for opencrypto(4).
  
  Reviewed by:  bz
  MFC after:    3 weeks

Modified:
  head/sys/opencrypto/cryptodev.c

Modified: head/sys/opencrypto/cryptodev.c
==============================================================================
--- head/sys/opencrypto/cryptodev.c     Thu Jul 29 20:41:40 2010        
(r210630)
+++ head/sys/opencrypto/cryptodev.c     Thu Jul 29 20:42:20 2010        
(r210631)
@@ -35,6 +35,8 @@
 #include <sys/cdefs.h>
 __FBSDID("$FreeBSD$");
 
+#include "opt_compat.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
@@ -56,6 +58,201 @@ __FBSDID("$FreeBSD$");
 #include <opencrypto/cryptodev.h>
 #include <opencrypto/xform.h>
 
+#ifdef COMPAT_FREEBSD32
+#include <sys/mount.h>
+#include <compat/freebsd32/freebsd32.h>
+
+struct session_op32 {
+       u_int32_t       cipher;
+       u_int32_t       mac;
+       u_int32_t       keylen;
+       u_int32_t       key;
+       int             mackeylen;
+       u_int32_t       mackey;
+       u_int32_t       ses;
+};
+
+struct session2_op32 {
+       u_int32_t       cipher;
+       u_int32_t       mac;
+       u_int32_t       keylen;
+       u_int32_t       key;
+       int             mackeylen;
+       u_int32_t       mackey;
+       u_int32_t       ses;
+       int             crid;
+       int             pad[4];
+};
+
+struct crypt_op32 {
+       u_int32_t       ses;
+       u_int16_t       op;
+       u_int16_t       flags;
+       u_int           len;
+       u_int32_t       src, dst;
+       u_int32_t       mac;
+       u_int32_t       iv;
+};
+
+struct crparam32 {
+       u_int32_t       crp_p;
+       u_int           crp_nbits;
+};
+
+struct crypt_kop32 {
+       u_int           crk_op;
+       u_int           crk_status;
+       u_short         crk_iparams;
+       u_short         crk_oparams;
+       u_int           crk_crid;
+       struct crparam32        crk_param[CRK_MAXPARAM];
+};
+
+struct cryptotstat32 {
+       struct timespec32       acc;
+       struct timespec32       min;
+       struct timespec32       max;
+       u_int32_t       count;
+};
+
+struct cryptostats32 {
+       u_int32_t       cs_ops;
+       u_int32_t       cs_errs;
+       u_int32_t       cs_kops;
+       u_int32_t       cs_kerrs;
+       u_int32_t       cs_intrs;
+       u_int32_t       cs_rets;
+       u_int32_t       cs_blocks;
+       u_int32_t       cs_kblocks;
+       struct cryptotstat32 cs_invoke;
+       struct cryptotstat32 cs_done;
+       struct cryptotstat32 cs_cb;
+       struct cryptotstat32 cs_finis;
+};
+
+#define        CIOCGSESSION32  _IOWR('c', 101, struct session_op32)
+#define        CIOCCRYPT32     _IOWR('c', 103, struct crypt_op32)
+#define        CIOCKEY32       _IOWR('c', 104, struct crypt_kop32)
+#define        CIOCGSESSION232 _IOWR('c', 106, struct session2_op32)
+#define        CIOCKEY232      _IOWR('c', 107, struct crypt_kop32)
+
+static void
+session_op_from_32(const struct session_op32 *from, struct session_op *to)
+{
+
+       CP(*from, *to, cipher);
+       CP(*from, *to, mac);
+       CP(*from, *to, keylen);
+       PTRIN_CP(*from, *to, key);
+       CP(*from, *to, mackeylen);
+       PTRIN_CP(*from, *to, mackey);
+       CP(*from, *to, ses);
+}
+
+static void
+session2_op_from_32(const struct session2_op32 *from, struct session2_op *to)
+{
+
+       session_op_from_32((const struct session_op32 *)from,
+           (struct session_op *)to);
+       CP(*from, *to, crid);
+}
+
+static void
+session_op_to_32(const struct session_op *from, struct session_op32 *to)
+{
+
+       CP(*from, *to, cipher);
+       CP(*from, *to, mac);
+       CP(*from, *to, keylen);
+       PTROUT_CP(*from, *to, key);
+       CP(*from, *to, mackeylen);
+       PTROUT_CP(*from, *to, mackey);
+       CP(*from, *to, ses);
+}
+
+static void
+session2_op_to_32(const struct session2_op *from, struct session2_op32 *to)
+{
+
+       session_op_to_32((const struct session_op *)from,
+           (struct session_op32 *)to);
+       CP(*from, *to, crid);
+}
+
+static void
+crypt_op_from_32(const struct crypt_op32 *from, struct crypt_op *to)
+{
+
+       CP(*from, *to, ses);
+       CP(*from, *to, op);
+       CP(*from, *to, flags);
+       CP(*from, *to, len);
+       PTRIN_CP(*from, *to, src);
+       PTRIN_CP(*from, *to, dst);
+       PTRIN_CP(*from, *to, mac);
+       PTRIN_CP(*from, *to, iv);
+}
+
+static void
+crypt_op_to_32(const struct crypt_op *from, struct crypt_op32 *to)
+{
+
+       CP(*from, *to, ses);
+       CP(*from, *to, op);
+       CP(*from, *to, flags);
+       CP(*from, *to, len);
+       PTROUT_CP(*from, *to, src);
+       PTROUT_CP(*from, *to, dst);
+       PTROUT_CP(*from, *to, mac);
+       PTROUT_CP(*from, *to, iv);
+}
+
+static void
+crparam_from_32(const struct crparam32 *from, struct crparam *to)
+{
+
+       PTRIN_CP(*from, *to, crp_p);
+       CP(*from, *to, crp_nbits);
+}
+
+static void
+crparam_to_32(const struct crparam *from, struct crparam32 *to)
+{
+
+       PTROUT_CP(*from, *to, crp_p);
+       CP(*from, *to, crp_nbits);
+}
+
+static void
+crypt_kop_from_32(const struct crypt_kop32 *from, struct crypt_kop *to)
+{
+       int i;
+
+       CP(*from, *to, crk_op);
+       CP(*from, *to, crk_status);
+       CP(*from, *to, crk_iparams);
+       CP(*from, *to, crk_oparams);
+       CP(*from, *to, crk_crid);
+       for (i = 0; i < CRK_MAXPARAM; i++)
+               crparam_from_32(&from->crk_param[i], &to->crk_param[i]);
+}
+
+static void
+crypt_kop_to_32(const struct crypt_kop *from, struct crypt_kop32 *to)
+{
+       int i;
+
+       CP(*from, *to, crk_op);
+       CP(*from, *to, crk_status);
+       CP(*from, *to, crk_iparams);
+       CP(*from, *to, crk_oparams);
+       CP(*from, *to, crk_crid);
+       for (i = 0; i < CRK_MAXPARAM; i++)
+               crparam_to_32(&from->crk_param[i], &to->crk_param[i]);
+}
+#endif
+
 struct csession {
        TAILQ_ENTRY(csession) next;
        u_int64_t       sid;
@@ -180,11 +377,27 @@ cryptof_ioctl(
        u_int64_t sid;
        u_int32_t ses;
        int error = 0, crid;
+#ifdef COMPAT_FREEBSD32
+       struct session2_op sopc;
+       struct crypt_op copc;
+       struct crypt_kop kopc;
+#endif
 
        switch (cmd) {
        case CIOCGSESSION:
        case CIOCGSESSION2:
-               sop = (struct session_op *)data;
+#ifdef COMPAT_FREEBSD32
+       case CIOCGSESSION32:
+       case CIOCGSESSION232:
+               if (cmd == CIOCGSESSION32) {
+                       session_op_from_32(data, (struct session_op *)&sopc);
+                       sop = (struct session_op *)&sopc;
+               } else if (cmd == CIOCGSESSION232) {
+                       session2_op_from_32(data, &sopc);
+                       sop = (struct session_op *)&sopc;
+               } else
+#endif
+                       sop = (struct session_op *)data;
                switch (sop->cipher) {
                case 0:
                        break;
@@ -294,7 +507,11 @@ cryptof_ioctl(
                }
 
                /* NB: CIOGSESSION2 has the crid */
-               if (cmd == CIOCGSESSION2) {
+               if (cmd == CIOCGSESSION2
+#ifdef COMPAT_FREEBSD32
+                   || cmd == CIOCGSESSION232
+#endif
+                       ) {
                        crid = SES2(sop)->crid;
                        error = checkforsoftware(crid);
                        if (error)
@@ -315,7 +532,11 @@ cryptof_ioctl(
                        goto bail;
                }
                sop->ses = cse->ses;
-               if (cmd == CIOCGSESSION2) {
+               if (cmd == CIOCGSESSION2
+#ifdef COMPAT_FREEBSD32
+                   || cmd == CIOCGSESSION232
+#endif
+                   ) {
                        /* return hardware/driver id */
                        SES2(sop)->crid = CRYPTO_SESID2HID(cse->sid);
                }
@@ -326,6 +547,15 @@ bail:
                        if (cria.cri_key)
                                free(cria.cri_key, M_XDATA);
                }
+#ifdef COMPAT_FREEBSD32
+               else {
+                       if (cmd == CIOCGSESSION32)
+                               session_op_to_32(sop, data);
+                       else if (cmd == CIOCGSESSION232)
+                               session2_op_to_32((struct session2_op *)sop,
+                                   data);
+               }
+#endif
                break;
        case CIOCFSESSION:
                ses = *(u_int32_t *)data;
@@ -336,25 +566,54 @@ bail:
                error = csefree(cse);
                break;
        case CIOCCRYPT:
-               cop = (struct crypt_op *)data;
+#ifdef COMPAT_FREEBSD32
+       case CIOCCRYPT32:
+               if (cmd == CIOCCRYPT32) {
+                       cop = &copc;
+                       crypt_op_from_32(data, cop);
+               } else
+#endif
+                       cop = (struct crypt_op *)data;
                cse = csefind(fcr, cop->ses);
                if (cse == NULL)
                        return (EINVAL);
                error = cryptodev_op(cse, cop, active_cred, td);
+#ifdef COMPAT_FREEBSD32
+               if (error == 0 && cmd == CIOCCRYPT32)
+                       crypt_op_to_32(cop, data);
+#endif
                break;
        case CIOCKEY:
        case CIOCKEY2:
+#ifdef COMPAT_FREEBSD32
+       case CIOCKEY32:
+       case CIOCKEY232:
+#endif
                if (!crypto_userasymcrypto)
                        return (EPERM);         /* XXX compat? */
-               mtx_lock(&Giant);
-               kop = (struct crypt_kop *)data;
-               if (cmd == CIOCKEY) {
+#ifdef COMPAT_FREEBSD32
+               if (cmd == CIOCKEY32 || cmd == CIOCKEY232) {
+                       kop = &kopc;
+                       crypt_kop_from_32(data, kop);
+               } else
+#endif
+                       kop = (struct crypt_kop *)data;
+               if (cmd == CIOCKEY
+#ifdef COMPAT_FREEBSD32
+                   || cmd == CIOCKEY32
+#endif
+                   ) {
                        /* NB: crypto core enforces s/w driver use */
                        kop->crk_crid =
                            CRYPTOCAP_F_HARDWARE | CRYPTOCAP_F_SOFTWARE;
                }
+               mtx_lock(&Giant);
                error = cryptodev_key(kop);
                mtx_unlock(&Giant);
+#ifdef COMPAT_FREEBSD32
+               if (cmd == CIOCKEY32 || cmd == CIOCKEY232)
+                       crypt_kop_to_32(kop, data);
+#endif
                break;
        case CIOCASYMFEAT:
                if (!crypto_userasymcrypto) {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to