svn commit: r211494 - stable/8/sys/opencrypto

Konstantin Belousov kib at FreeBSD.org
Thu Aug 19 08:50:12 UTC 2010


Author: kib
Date: Thu Aug 19 08:50:11 2010
New Revision: 211494
URL: http://svn.freebsd.org/changeset/base/211494

Log:
  MFC r210631:
  Add compat32 shims for opencrypto(4).

Modified:
  stable/8/sys/opencrypto/cryptodev.c
Directory Properties:
  stable/8/sys/   (props changed)
  stable/8/sys/amd64/include/xen/   (props changed)
  stable/8/sys/cam/   (props changed)
  stable/8/sys/cddl/contrib/opensolaris/   (props changed)
  stable/8/sys/contrib/dev/acpica/   (props changed)
  stable/8/sys/contrib/pf/   (props changed)
  stable/8/sys/dev/xen/xenpci/   (props changed)

Modified: stable/8/sys/opencrypto/cryptodev.c
==============================================================================
--- stable/8/sys/opencrypto/cryptodev.c	Thu Aug 19 08:11:07 2010	(r211493)
+++ stable/8/sys/opencrypto/cryptodev.c	Thu Aug 19 08:50:11 2010	(r211494)
@@ -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) {


More information about the svn-src-all mailing list