summaryrefslogtreecommitdiffstats
path: root/sys/opencrypto
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2010-07-29 20:42:20 +0000
committerkib <kib@FreeBSD.org>2010-07-29 20:42:20 +0000
commit4fd4e2aac4a5e65d384e1bc13a5fe945f55204c8 (patch)
tree005d913dbc167c623ece4b29564241f4858e50ac /sys/opencrypto
parent516c7c4bda55d5cabead12abdfca042db4b914fa (diff)
downloadFreeBSD-src-4fd4e2aac4a5e65d384e1bc13a5fe945f55204c8.zip
FreeBSD-src-4fd4e2aac4a5e65d384e1bc13a5fe945f55204c8.tar.gz
Add compat32 shims for opencrypto(4).
Reviewed by: bz MFC after: 3 weeks
Diffstat (limited to 'sys/opencrypto')
-rw-r--r--sys/opencrypto/cryptodev.c273
1 files changed, 266 insertions, 7 deletions
diff --git a/sys/opencrypto/cryptodev.c b/sys/opencrypto/cryptodev.c
index 6ba4425..ddc8e75 100644
--- a/sys/opencrypto/cryptodev.c
+++ b/sys/opencrypto/cryptodev.c
@@ -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) {
OpenPOWER on IntegriCloud