summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@gnutls.org>2009-12-04 01:34:03 +0200
committerNikos Mavrogiannopoulos <nmav@gnutls.org>2009-12-04 01:34:03 +0200
commit7e13b2bef6fd81b5eadeaa982e7e82f82ae59209 (patch)
tree1797adabd90ca2faec674d137fbf21b737c5ba23
parent0ae0d8cf7ba637036e1ad73c74b55b0cd084c64a (diff)
downloadcryptodev-linux-7e13b2bef6fd81b5eadeaa982e7e82f82ae59209.tar.gz
cryptodev-linux-7e13b2bef6fd81b5eadeaa982e7e82f82ae59209.tar.xz
cryptodev-linux-7e13b2bef6fd81b5eadeaa982e7e82f82ae59209.zip
Revert "Added CIOCCRYPTV that will encrypt/hash iovectors.". This
is a cryptodev release that intends to be fully compatible with OpenBSD and FreeBSD APIs. This reverts commit 30181c1a49a63fddc97dd10dbac1b49568aede1f. Conflicts: cryptodev.c
-rw-r--r--cryptodev.c188
-rw-r--r--cryptodev.h29
2 files changed, 77 insertions, 140 deletions
diff --git a/cryptodev.c b/cryptodev.c
index 5380804..17a4708 100644
--- a/cryptodev.c
+++ b/cryptodev.c
@@ -401,7 +401,10 @@ crypto_get_session_by_sid(struct fcrypt *fcr, uint32_t sid)
return ses_ptr;
}
-static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv)
+/* This is the main crypto function - feed it with plaintext
+ and get a ciphertext (or vice versa :-) */
+static int
+crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
{
char *data, ivp[EALG_MAX_BLOCK_LEN];
char __user *src, __user *dst;
@@ -411,7 +414,6 @@ static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv)
size_t nbytes, bufsize;
int ret = 0;
uint8_t hash_output[HASH_MAX_LEN];
- int blocksize=1, i;
struct blkcipher_desc bdesc = {
.flags = CRYPTO_TFM_REQ_MAY_SLEEP,
};
@@ -420,27 +422,29 @@ static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv)
};
- if (unlikely(copv->op != COP_ENCRYPT && copv->op != COP_DECRYPT)) {
- dprintk(1, KERN_DEBUG, "invalid operation op=%u\n", copv->op);
+ if (unlikely(cop->op != COP_ENCRYPT && cop->op != COP_DECRYPT)) {
+ dprintk(1, KERN_DEBUG, "invalid operation op=%u\n", cop->op);
return -EINVAL;
}
- ses_ptr = crypto_get_session_by_sid(fcr, copv->ses);
+ ses_ptr = crypto_get_session_by_sid(fcr, cop->ses);
if (!ses_ptr) {
- dprintk(1, KERN_ERR, "invalid session ID=0x%08X\n", copv->ses);
+ dprintk(1, KERN_ERR, "invalid session ID=0x%08X\n", cop->ses);
return -EINVAL;
}
+ nbytes = cop->len;
data = (char*)__get_free_page(GFP_KERNEL);
if (unlikely(!data)) {
ret = -ENOMEM;
goto out_unlock;
}
+ bufsize = PAGE_SIZE < nbytes ? PAGE_SIZE : nbytes;
+ nbytes = cop->len;
bdesc.tfm = ses_ptr->tfm;
hdesc.tfm = ses_ptr->hash_tfm;
-
if (hdesc.tfm) {
ret = crypto_hash_init(&hdesc);
if (unlikely(ret)) {
@@ -450,97 +454,81 @@ static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv)
}
}
- if (ses_ptr->tfm) {
- blocksize = crypto_blkcipher_blocksize(ses_ptr->tfm);
- ivsize = crypto_blkcipher_ivsize(ses_ptr->tfm);
-
- if (copv->iv) {
- copy_from_user(ivp, copv->iv, ivsize);
- crypto_blkcipher_set_iv(ses_ptr->tfm, ivp, ivsize);
- }
- }
-
- dst = copv->dst;
+ if (bdesc.tfm) {
+ int blocksize = crypto_blkcipher_blocksize(bdesc.tfm);
- for (i=0;i<copv->iovec_cnt;i++) {
- nbytes = copv->iovec[i].len;
-
- if (unlikely(bdesc.tfm && (copv->iovec[i].op_flags & IOP_CIPHER) && (nbytes % blocksize))) {
+ if (unlikely(nbytes % blocksize)) {
dprintk(1, KERN_ERR,
"data size (%zu) isn't a multiple of block size (%u)\n",
- nbytes, crypto_blkcipher_blocksize(ses_ptr->tfm));
+ nbytes, blocksize);
ret = -EINVAL;
goto out_unlock;
}
- bufsize = PAGE_SIZE < nbytes ? PAGE_SIZE : nbytes;
+ ivsize = crypto_blkcipher_ivsize(bdesc.tfm);
- src = copv->iovec[i].src;
+ if (cop->iv) {
+ copy_from_user(ivp, cop->iv, ivsize);
+ crypto_blkcipher_set_iv(bdesc.tfm, ivp, ivsize);
+ }
+ }
- while(nbytes > 0) {
- size_t current_len = nbytes > bufsize ? bufsize : nbytes;
+ src = cop->src;
+ dst = cop->dst;
- copy_from_user(data, src, current_len);
- sg_set_buf(&sg, data, current_len);
+ while(nbytes > 0) {
+ size_t current_len = nbytes > bufsize ? bufsize : nbytes;
- /* Always hash before encryption and after decryption. Maybe
- * we should introduce a flag to switch... TBD later on.
- */
- if (copv->op == COP_ENCRYPT) {
- if (hdesc.tfm && (copv->iovec[i].op_flags & IOP_HASH)) {
- ret = crypto_hash_update(&hdesc, &sg, current_len);
- if (unlikely(ret)) {
- dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
- goto out;
- }
- }
- if (bdesc.tfm && (copv->iovec[i].op_flags & IOP_CIPHER)) {
- ret = crypto_blkcipher_encrypt(&bdesc, &sg, &sg, current_len);
-
- if (unlikely(ret)) {
- dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
- goto out;
- }
- copy_to_user(dst, data, current_len);
- dst += current_len;
- }
- } else {
- if (bdesc.tfm && (copv->iovec[i].op_flags & IOP_CIPHER)) {
- ret = crypto_blkcipher_decrypt(&bdesc, &sg, &sg, current_len);
+ copy_from_user(data, src, current_len);
- if (unlikely(ret)) {
- dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
- goto out;
- }
- copy_to_user(dst, data, current_len);
- dst += current_len;
+ sg_set_buf(&sg, data, current_len);
+ /* Always hash before encryption and after decryption. Maybe
+ * we should introduce a flag to switch... TBD later on.
+ */
+ if (cop->op == COP_ENCRYPT) {
+ if (hdesc.tfm) {
+ ret = crypto_hash_update(&hdesc, &sg, current_len);
+ if (unlikely(ret)) {
+ dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
+ goto out;
}
+ }
+ if (bdesc.tfm) {
+ ret = crypto_blkcipher_encrypt(&bdesc, &sg, &sg, current_len);
- if (hdesc.tfm && (copv->iovec[i].op_flags & IOP_HASH)) {
- ret = crypto_hash_update(&hdesc, &sg, current_len);
- if (unlikely(ret)) {
- dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
- goto out;
- }
+ if (unlikely(ret)) {
+ dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
+ goto out;
}
+ copy_to_user(dst, data, current_len);
+ dst += current_len;
}
+ } else {
+ if (bdesc.tfm) {
+ ret = crypto_blkcipher_decrypt(&bdesc, &sg, &sg, current_len);
- nbytes -= current_len;
- src += current_len;
- }
+ if (unlikely(ret)) {
+ dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
+ goto out;
+ }
+ copy_to_user(dst, data, current_len);
+ dst += current_len;
-#if defined(CRYPTODEV_STATS)
- if (enable_stats) {
- /* this is safe - we check cop->op at the function entry */
- ses_ptr->stat[copv->op] += copv->iovec[i].len;
- if (ses_ptr->stat_max_size < copv->iovec[i].len)
- ses_ptr->stat_max_size = copv->iovec[i].len;
- ses_ptr->stat_count++;
- }
-#endif
+ }
+ if (hdesc.tfm) {
+ ret = crypto_hash_update(&hdesc, &sg, current_len);
+ if (unlikely(ret)) {
+ dprintk(0, KERN_ERR, "CryptoAPI failure: %d\n",ret);
+ goto out;
+ }
+ }
+ }
+
+ nbytes -= current_len;
+ src += current_len;
}
if (hdesc.tfm) {
@@ -550,8 +538,18 @@ static int crypto_runv(struct fcrypt *fcr, struct crypt_opv *copv)
goto out;
}
- copy_to_user(copv->mac, hash_output, crypto_hash_digestsize(ses_ptr->hash_tfm));
+ copy_to_user(cop->mac, hash_output, crypto_hash_digestsize(ses_ptr->hash_tfm));
+ }
+
+#if defined(CRYPTODEV_STATS)
+ if (enable_stats) {
+ /* this is safe - we check cop->op at the function entry */
+ ses_ptr->stat[cop->op] += cop->len;
+ if (ses_ptr->stat_max_size < cop->len)
+ ses_ptr->stat_max_size = cop->len;
+ ses_ptr->stat_count++;
}
+#endif
out:
free_page((unsigned long)data);
@@ -562,33 +560,6 @@ out_unlock:
return ret;
}
-/* This is the main crypto function - feed it with plaintext
- and get a ciphertext (or vice versa :-) */
-static int crypto_run(struct fcrypt *fcr, struct crypt_op *cop)
-{
- struct crypt_opv copv;
- struct crypt_iovec iovec;
-
- iovec.src = cop->src;
- iovec.len = cop->len;
- iovec.op_flags = IOP_CIPHER|IOP_HASH;
-
- copv.op = cop->op;
- copv.ses = cop->ses;
- copv.flags = cop->flags;
- copv.iovec = &iovec;
- copv.iovec_cnt = 1;
-
- copv.dst = cop->dst;
- copv.mac = cop->mac;
- copv.iv = cop->iv;
-
- return crypto_runv(fcr, &copv);
-
-}
-
-
-
/* ====== /dev/crypto ====== */
static int
@@ -644,7 +615,6 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
int __user *p = (void __user *)arg;
struct session_op sop;
struct crypt_op cop;
- struct crypt_opv copv;
struct fcrypt *fcr = filp->private_data;
uint32_t ses;
int ret, fd;
@@ -680,12 +650,6 @@ cryptodev_ioctl(struct inode *inode, struct file *filp,
copy_to_user((void*)arg, &cop, sizeof(cop));
return ret;
- case CIOCCRYPTV:
- copy_from_user(&cop, (void*)arg, sizeof(copv));
- ret = crypto_runv(fcr, &copv);
- copy_to_user((void*)arg, &copv, sizeof(copv));
- return ret;
-
default:
return -EINVAL;
}
diff --git a/cryptodev.h b/cryptodev.h
index 55c3279..fcdd006 100644
--- a/cryptodev.h
+++ b/cryptodev.h
@@ -75,7 +75,7 @@ struct crypt_op {
uint32_t ses; /* from session_op->ses */
#define COP_DECRYPT 0
#define COP_ENCRYPT 1
- uint16_t op; /* ie. COP_ENCRYPT */
+ uint32_t op; /* ie. COP_ENCRYPT */
uint32_t flags; /* unused */
size_t len;
@@ -84,30 +84,6 @@ struct crypt_op {
void *iv;
};
-struct crypt_iovec {
-#define IOP_CIPHER 1
-#define IOP_HASH 2
- uint16_t op_flags; /* ie. IOP_CIPHER|IOP_HASH */
- void *src;
- size_t len;
-};
-
-/* ioctl parameter to request a crypt/decrypt operation against a session */
-struct crypt_opv {
- uint32_t ses; /* from session_op->ses */
- #define COP_DECRYPT 0
- #define COP_ENCRYPT 1
- uint16_t op; /* ie. COP_ENCRYPT */
- uint32_t flags; /* unused */
-
- struct crypt_iovec* iovec;
- uint16_t iovec_cnt;
-
- void *dst;
- void *mac;
- void *iv;
-};
-
/* clone original filedescriptor */
#define CRIOGET _IOWR('c', 101, uint32_t)
@@ -124,9 +100,6 @@ struct crypt_opv {
#define CIOCKEY _IOWR('c', 105, void *)
#define CIOCASYMFEAT _IOR('c', 106, uint32_t)
-/* request encryption/decryptions of a given buffer vector */
-#define CIOCCRYPTV _IOWR('c', 107, struct crypt_opv)
-
#endif /* _CRYPTODEV_H */
/* unused structures */